2009-06-18 21 views
2

私はWPFでメニューを持っています(メニューアイテムあり)。残念ながら、メニュー見出しをクリックすると、メニューが右に開きます。問題は、右に、重複したくないものがあることです。メニューを左に開くようにWPFに指示するにはどうすればよいですか?コントロールテンプレートを行う必要がありますか? (コントロールテンプレートはそのような基本的なスタイルの変更にはとても重いと思われる)。WPFでメニューを左に開くにはどうすればいいですか?

ありがとうございます!

KSG

答えて

10

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

ポップアップが開く場所を変更するには、ポップアップのPlacementModeを設定する必要があります。 propaショートカットを使用してAttachedProperty(または残りの部分を実装したい場合はプロパティ)を生成することができます。 PropertyMetadataにコールバックを追加する必要がありますが、AttachedPropertyがXAMLのコントロールにインラインで設定されている場合、コントロール全体が完全に構築される前にコールバックが発生します。 MenuItemのテンプレートが確実に適用され、ポップアップが存在していて、その値を設定しようとすると、まだロードされていない場合はLoadedイベントにアタッチできます。 ロードされたら、テンプレートからPopupを取得したいとします。MenuItem classを見ると、Popupの名前を「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> 
+0

ありがとうございます。それは私がここで使われている一般的な方法が好きで、実際にコードが掲載されているのは実際には良いコードです。素晴らしい応答。 –

関連する問題