2009-06-18 120 views
2

我有一個WPF菜單(帶menuitems)。不幸的是,當我點擊菜單標題時,它會打開右側的菜單。問題是右邊有東西,我不希望它重疊。我如何讓WPF打開左側的菜單?我需要做一個控制模板嗎? (對於這種基本的風格變化,控制模板顯得如此沉重)。如何讓菜單在WPF左側打開?

謝謝!

KSG

回答

10

雖然你可以創建一個的ControlTemplate做到這一點像他們這樣做here,我同意,它只是修改了的MenuItems的一部分的一個值的繁瑣方法。相反,我認爲這是使用AttachedProperty的好地方。我們可以創建類似ContextMenuService的東西,但對於彈出窗口(事實上,我有點驚訝,它不是內置的)。

要更改彈出窗口的位置,我們要設置Popup的PlacementMode。我們可以使用propa快捷鍵來生成我們的AttachedProperty(或者如果您想實施其他的屬性)。我們需要給我們的PropertyMetadata添加一個回調,但是如果AttachedProperty被設置在XAML中的控件上,那麼回調將在整個控件完全構建之前觸發。爲了確保應用MenuItem的模板,並在彈出窗口存在,然後設置它的值,我們可以將其附加到Loaded事件,如果它尚未加載。 加載後,我們希望從模板中檢索Popup,如果我們查看MenuItem class,我們可以看到它有一個TemplatePartAttribute,將Popup的名稱定義爲「PART_Popup」。一旦我們有了,我們可以在MenuItem的Popup上設置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

謝謝。這是訣竅,我喜歡這裏使用的一般方法,發佈的代碼實際上是很好的工作代碼。偉大的迴應。 – 2009-06-19 19:57:53

相關問題