2

WPF を使用して「メガ メニュー」スタイルのメニューを実装しようとしています。Web デザインのメガ メニューの例については、こちらを参照してください。

これまでのところ、TextBlocks をメニューの最上位レベルとして使用し、マウス ホバー イベントを使用してテキスト ブロックの下に表示される追加のウィンドウを表示することで、同様のインターフェイスを作成しようとしました。これは面倒で柔軟性がなく、将来の変更では TextBlocks を動的に追加/削除する必要があります。

スタイルを大幅に変更できることはわかっているため、WPF メニュー コントロールの使用を検討しましたが、メニュー コントロールが使用する階層モデルを使用して複数列のレイアウトを作成する方法は見たことがありません。

これを行うより良い方法はありますか?カスタム ウィンドウと相対的な配置に固執する必要がありますか? 誰かがすでに実装されているこの例を教えてもらえますか?

4

4 に答える 4

1

カスタムWindowsとポジショニングを使用する代わりに、ポップアップコントロールを使用できます。この設定を使用しStaysOpen=falseて、ユーザーが画面外をクリックしたときに閉じることができます。

ホバーする代わりにメニュー項目をクリックすることに落ち着くことができる場合は、次のカスタムコントロールが機能します。

[TemplatePart(Name="PART_HoverArea", Type=typeof(FrameworkElement))]
[TemplatePart(Name="PART_Popup", Type=typeof(Popup))]
public class MegaMenuItem : HeaderedContentControl
{
    private FrameworkElement hoverArea;
    private Popup popup;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        // Unhook old template
        if (hoverArea != null)
        {
            hoverArea.PreviewMouseUp -= ShowPopupOnMouseDown;
        }

        hoverArea = null;
        popup = null;

        if (Template == null)
            return;

        // Hook up new template
        hoverArea = (FrameworkElement)Template.FindName("PART_HoverArea", this);
        popup = (Popup)Template.FindName("PART_Popup", this);
        if (hoverArea == null || popup == null)
            return;

        hoverArea.PreviewMouseUp += ShowPopupOnMouseDown;
    }

    private void ShowPopupOnMouseDown(object sender, MouseEventArgs e)
    {
        popup.PlacementTarget = hoverArea;
        popup.Placement = PlacementMode.Bottom;
        popup.StaysOpen = false;
        popup.IsOpen = true;
    }
}

あなたはそれを表示するためのスタイルが必要になるでしょう-このようなもの。PART_テンプレートのパーツ名に注意してください。

<Style TargetType="WpfApplication14:MegaMenuItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="WpfApplication14:MegaMenuItem">
                <Grid>
                    <Border Name="PART_HoverArea" Background="#fb9c3b" BorderBrush="White" BorderThickness="0,0,1,0">
                        <ContentPresenter Content="{TemplateBinding Header}" />
                    </Border>

                    <Popup 
                        Name="PART_Popup" 
                        PlacementTarget="{Binding ElementName=HoverArea}"
                        >
                        <Border MinWidth="100" MaxWidth="400" MinHeight="40" MaxHeight="200" Background="#0d81c3">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </Border>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>    
</Style>

メニューのXAMLは次のようになります。

<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
    <WpfApplication14:MegaMenuItem Header="Parent 1">
        <WrapPanel Margin="5">
            <TextBlock Text="Put any content you want here" Margin="5" />
            <TextBlock Text="Put any content you want here" Margin="5" />
            <TextBlock Text="Put any content you want here" Margin="5" />
        </WrapPanel>
    </WpfApplication14:MegaMenuItem>
    <WpfApplication14:MegaMenuItem Header="Parent 2">
        <WrapPanel Margin="5">
            <TextBlock Text="Put any content you want here" Margin="5" />
            <TextBlock Text="Put any content you want here" Margin="5" />
            <TextBlock Text="Put any content you want here" Margin="5" />
        </WrapPanel>
    </WpfApplication14:MegaMenuItem>
</StackPanel>

ポップアップがフォーカスを盗む方法のため、メニューをホバーに表示するのははるかに困難です(メニューを表示することはできますが、別のメニューの上にマウスを置くと簡単に非表示にすることはできません)。そのためには、カスタムウィンドウの方がうまくいくかもしれません。

于 2011-04-05T00:13:05.093 に答える
1

これを行うためにリボン コントロールを後付けできるのでしょうか? タブ、ラベル、列などを提供します。

この UI デザインは慎重に使用し、ユーザーが特に要求した場合にのみ開閉するようにしてください。表示している Web サイトの上にポップアップ メガ メニューが表示され、それをクリックして消えた場合を除いて閉じることができないのは、非常に煩わしいことです。

于 2011-04-04T20:29:04.850 に答える
1

HeaderedItemsControlを使用しPanelて、ニーズに合わせて交換することができます。デフォルトでは a を使用しますが、StackPanela のWrapPanel方が適している場合もあります。ポップアウトとマウスオーバーの動作はデフォルトでは存在しないため、実装する必要があります。

より堅牢なアプローチは、カスタムExpanderを活用することです。それはあなたが求めているポップアウト動作を提供し、リンクされたウォークスルーはマウスオーバー動作を提供するためです。

于 2011-04-04T20:06:35.770 に答える
0

カスタムウィンドウと相対位置は、基本的にWPF Menu / MenuItemコントロールの動作方法です...しかし、ご存知のように、それは重要です。最善の策は、必要に応じてMenu/MenuItemコントロールを再テンプレート化することです。

于 2011-04-04T19:54:08.977 に答える