3

WPFに(menuitemsを含む)メニューがあります。残念ながら、メニューの見出しをクリックすると、右側のメニューが開きます。問題は、右側に重ならないものがあることです。左側のメニューを開くようにWPFに指示するにはどうすればよいですか?コントロールテンプレートを作成する必要がありますか?(コントロールテンプレートは、このような基本的なスタイルの変更には非常に手間がかかるようです)。

ありがとう!

KSG

4

1 に答える 1

15

ここで行うようにこれを行うためのControlTemplateを作成できますが、MenuItemの一部の1つの値を変更するだけの面倒な方法であることに同意します。代わりに、これはAttachedPropertyを使用するのに最適な場所だと思います。ContextMenuServiceと同じように作成できますが、ポップアップ用です(実際、組み込みではないことに少し驚いています)。

ポップアップが開く場所を変更するには、ポップアップのPlacementModeを設定します。propaショートカットを使用して、AttachedProperty(または残りを実装する場合はプロパティ)を生成できます。PropertyMetadataにコールバックを追加する必要がありますが、AttachedPropertyがXAMLのコントロールにインラインで設定されている場合、コントロール全体が完全に構築される前にコールバックが起動します。MenuItemのテンプレートが適用され、その値を設定する前にポップアップが存在することを確認するために、まだロードされていない場合は、Loadedイベントにアタッチするだけです。ロードされたら、テンプレートからポップアップを取得します。MenuItemクラスを見るとポップアップの名前を「PART_Popup」として定義するTemplatePartAttributeがあることがわかります。それができたら、MenuItemのポップアップでPlacementModeを設定できます。

    public static PlacementMode GetMenuPlacement(DependencyObject obj)
    {
        return (PlacementMode)obj.GetValue(MenuPlacementProperty);
    }

    public static void SetMenuPlacement(DependencyObject obj, PlacementMode value)
    {
        obj.SetValue(MenuPlacementProperty, value);
    }

    // Using a DependencyProperty as the backing store for MenuPlacement.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MenuPlacementProperty =
        DependencyProperty.RegisterAttached("MenuPlacement",
        typeof(PlacementMode),
        typeof(Window1),
        new FrameworkPropertyMetadata(PlacementMode.Bottom, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnMenuPlacementChanged)));

    private static void OnMenuPlacementChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var menuItem = o as MenuItem;
        if (menuItem != null)
        {
            if (menuItem.IsLoaded)
            {
                SetPopupPlacement(menuItem, (PlacementMode)e.NewValue);
            }
            else
            {
                menuItem.Loaded += new RoutedEventHandler((m, v) => SetPopupPlacement(menuItem, (PlacementMode)e.NewValue));
            }
        }
    }

    private static void SetPopupPlacement(MenuItem menuItem, PlacementMode placementMode)
    {
        Popup popup = menuItem.Template.FindName("PART_Popup", menuItem) as Popup;
        if (popup != null)
        {
            popup.Placement = placementMode;
        }
    }

AttachedPropertyができたので、UIでポップアップの配置を簡単に変更できます。

<Menu>
    <MenuItem Header="Item 1"
              local:Window1.MenuPlacement="Right">
        <MenuItem Header="SubItem 1" />
        <MenuItem Header="SubItem 2" />
        <MenuItem Header="SubItem 3" />
        <MenuItem Header="SubItem 4" />
    </MenuItem>
    <MenuItem Header="Item 2"
              local:Window1.MenuPlacement="Left">
        <MenuItem Header="SubItem 5" />
        <MenuItem Header="SubItem 6" />
        <MenuItem Header="SubItem 7" />
        <MenuItem Header="SubItem 8" />
    </MenuItem>
    <MenuItem Header="Item 3"
              local:Window1.MenuPlacement="Mouse">
        <MenuItem Header="SubItem 9" />
        <MenuItem Header="SubItem 10" />
        <MenuItem Header="SubItem 11" />
        <MenuItem Header="SubItem 12" />
    </MenuItem>
</Menu>
于 2009-06-18T07:43:04.353 に答える