2011-01-28 44 views
19

我正在尋找互聯網上的解決方案,但無法在我的示例中找到它。我需要在後臺代碼生成的上下文菜單項之間添加一個分隔符。我試圖用下面的代碼行添加它,但沒有成功。如何在動態創建的ContextMenu中添加水平分隔符?

this.Commands.Add(new ToolStripSeparator()); 

我想知道是否有人可以提供幫助。先謝謝你。

上下文菜單XAML:

<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}"> 
    <Setter Property="ContextMenu"> 
     <Setter.Value> 
      <ContextMenu ItemsSource="{Binding Commands}"> 
       <ContextMenu.ItemContainerStyle> 
        <Style TargetType="{x:Type MenuItem}"> 
         <Setter Property="Command" Value="{Binding}" /> 
         <Setter Property="Header" Value="{Binding Path=Text}" /> 
         <Setter Property="CommandParameter" Value="{Binding Path=Parameter}" /> 
        </Style> 
       </ContextMenu.ItemContainerStyle> 
      </ContextMenu> 
     </Setter.Value> 
    </Setter> 

C#,在該方法中加入:

this.Commands = new ObservableCollection<ICommand>(); 
     this.Commands.Add(MainWindow.AddRole1); 
     this.Commands.Add(MainWindow.AddRole2); 
     this.Commands.Add(MainWindow.AddRole3); 
     this.Commands.Add(MainWindow.AddRole4); 
     //this.Add(new ToolStripSeparator()); 
     this.Commands.Add(MainWindow.AddRole5); 
     this.Commands.Add(MainWindow.AddRole6); 
     this.Commands.Add(MainWindow.AddRole7); 

回答

12

或者,而不是讓你的文本菜單綁定到命令的集合,將其綁定到FrameworkElements的集合,那麼你可以直接添加任何的MenuItems或分離器的收集和讓菜單控制完成所有的模板。 ...

<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}"> 
    <Setter Property="ContextMenu"> 
     <Setter.Value> 
      <ContextMenu ItemsSource="{Binding Commands}" /> 
     </Setter.Value> 
    </Setter> 
</Style> 

C#:

this.Commands = new ObservableCollection<FrameworkElement>(); 

this.Commands.Add(new MenuItem {Header = "Menuitem 2", Command = MainWindow.AddRole1}); 
this.Commands.Add(new MenuItem {Header = "Menuitem 2", Command = MainWindow.AddRole2}); 
this.Commands.Add(new MenuItem {Header = "Menuitem 3", Command = MainWindow.AddRole3}); 
this.Commands.Add(new MenuItem {Header = "Menuitem 4", Command = MainWindow.AddRole4}); 

this.Commands.Add(new Separator); 

this.Commands.Add(new MenuItem {Header = "Menuitem 5", Command = MainWindow.AddRole5}); 
this.Commands.Add(new MenuItem {Header = "Menuitem 6", Command = MainWindow.AddRole6}); 
this.Commands.Add(new MenuItem {Header = "Menuitem 7", Command = MainWindow.AddRole7}); 

就用這種方法在我的應用程序 - 分隔看起來更好,這樣也。

40

我這樣做一次,使用的null作爲我的分隔符。從XAML,然後我風格的模板,使用分離器,如果在DataContext爲null

後面的代碼:

this.Commands.Add(MainWindow.AddRole4); 
this.Add(null); 
this.Commands.Add(MainWindow.AddRole5); 

XAML是這樣的:

<ContextMenu.ItemContainerStyle> 
    <Style TargetType="{x:Type MenuItem}"> 
     <Setter Property="Command" Value="{Binding}" /> 
     <Setter Property="Header" Value="{Binding Path=Text}" /> 
     <Setter Property="CommandParameter" Value="{Binding Path=Parameter}" /> 

     <Style.Triggers> 
      <DataTrigger Binding="{Binding }" Value="{x:Null}"> 
       <Setter Property="Template" Value="{StaticResource MenuSeparatorTemplate}" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</ContextMenu.ItemContainerStyle> 

希望我得到的語法對 - 我沒有在這臺機器上的IDE來驗證代碼

編輯

以下是上下文菜單分隔符的示例模板。我將它放在ContextMenu.Resources中,但只要ContextMenu可以訪問它,您可以將它放在應用程序的任何位置。

<ContextMenu.Resources> 
    <ControlTemplate x:Key="MenuSeparatorTemplate"> 
     <Separator /> 
    </ControlTemplate> 
</ContextMenu.Resources> 
+0

感謝您的想法。但是,它還沒有工作。我還無法插入分隔符。我將值更改爲「Value =」{DynamicResource MenuSeparatorTemplate}「'並且能夠調試解決方案。結果是分隔符不可見,並且該區域在空白菜單項上具有翻轉狀態。我想知道是否可以修復。 – vladc77 2011-01-28 18:56:55

+0

你需要創建`MenuSeparatorTemplate`。由於它沒有創建,所以沒有顯示任何內容。 – Rachel 2011-01-28 19:30:21

+0

如何從datatrigger訪問泛型分隔符模板? – vladc77 2011-01-28 19:40:01

0

使用ItemTemplateSelector:

public class MenuItemTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate SeparatorTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var menuItem = container.GetVisualParent<MenuItem>(); 
     if (menuItem == null) 
     { 
      throw new Exception("Unknown MenuItem type"); 
     } 

     if (menuItem.DataContext == null) 
     { 
      return SeparatorTemplate; 
     } 

     return menuItem.ItemTemplate; 
    } 
} 

的XAML:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" 

           ItemsSource="{Binding Path=ViewContentMenuItems}" > 
           <ContextMenu.ItemTemplateSelector> 
            <templateSelectors:MenuItemTemplateSelector> 
             <templateSelectors:MenuItemTemplateSelector.SeparatorTemplate> 
              <DataTemplate> 
               <Separator /> 
              </DataTemplate> 
             </templateSelectors:MenuItemTemplateSelector.SeparatorTemplate> 
            </templateSelectors:MenuItemTemplateSelector> 
           </ContextMenu.ItemTemplateSelector> 
          </ContextMenu> 

在模型:

public ObservableCollection<MenuItem> ViewContentMenuItems 
    { 
     get 
     { 
      var temp = new ObservableCollection<MenuItem>(); 
      temp.Add(null); 
      temp.Add(CreateFolderMenuItem); 
      return temp; 
     } 
    } 
private MenuItem CreateFolderMenuItem 
    { 
     get 
     { 
      var createFolderMenuItem = new MenuItem() 
      { 
       Header = "New Folder", 
       Icon = new Image 
       { 
        Source = new BitmapImage(new Uri("/icons/folderWinCreate.png", UriKind.Relative)), 
        Height = 16, 
        Width = 16 
       } 
      }; 

      Message.SetAttach(createFolderMenuItem, "CreateDocumentsFolder");//Caliburn example 
      return createFolderMenuItem; 
     } 
    } 
0

要正確地爲MVVM你必須定義自己的產品界面做到這一點( FEIMenuItem),爲菜單/創建派生類的ContextMenu菜單項,這些類中重寫下列虛擬保護方法:

ItemsControl.PrepareContainerForItemOverride 
ItemsControl.ClearContainerForItemOverride 
ItemsControl.GetContainerForItemOverride 
ItemsControl.IsItemItsOwnContainerOverride 

確保此方法創建物品IMenuItem您的新貨物的容器來自MenuItem鍵入綁定所有需要的屬性,在這裏您可以區分不同類型的IMenuItem以顯示正常項目,分隔符或其他一些其他屬性。對於未知類型的調用庫實現。

現在,如果你將綁定新源自菜單/文本菜單控制與收集IMenuItem的ItemsSource屬性,它會告訴你預計無需到現在視圖 - 結果在ViewModel方面的東西。

2

我修改了上面提到的Rachel解決方案來糾正分隔符樣式。我意識到這篇文章已經過時了,但仍然是Google的最佳成果之一。在我的情況下,我將它用於菜單和ContextMenu,但同樣適用。

XAML

<Menu ItemsSource="{Binding MenuItems}"> 
    <Menu.Resources> 
     <ControlTemplate x:Key="MenuSeparatorTemplate"> 
      <Separator> 
       <Separator.Style> 
        <Style TargetType="{x:Type Separator}" BasedOn="{StaticResource ResourceKey={x:Static MenuItem.SeparatorStyleKey}}"/> 
       </Separator.Style> 
      </Separator> 
     </ControlTemplate> 
     <Style TargetType="{x:Type MenuItem}"> 
      <Setter Property="Header" Value="{Binding MenuItemHeader}" /> 
      <Setter Property="Command" Value="{Binding MenuItemCommand}" /> 
      <Setter Property="CommandParameter" Value="{Binding MenuItemCommandParameter}" /> 
      <Setter Property="ItemsSource" Value="{Binding MenuItemCollection}" /> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding }" Value="{x:Null}"> 
        <Setter Property="Template" Value="{StaticResource MenuSeparatorTemplate}" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Menu.Resources> 
</Menu> 

Without Separator Style Change

With Separator Style Change

相關問題