Given the following XAML snippet:
<UserControl.Resources>
<ResourceDictionary>
<Style x:Key="ContextMenuItemStyle">
<Setter Property="MenuItem.Header" Value="{Binding Text}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding 开发者_StackOverflow中文版Children}"/>
<Setter Property="MenuItem.Command" Value="{Binding Command}" />
</Style>
<ContextMenu x:Key="contextMenu" ItemsSource="{Binding MenuOptions}" ItemContainerStyle="{StaticResource ContextMenuItemStyle}" />
</ResourceDictionary>
</UserControl.Resources>
<DockPanel>
<TextBox Height="30" DockPanel.Dock="Top" ContextMenu="{StaticResource contextMenu}" />
<Button Content="Add Menu Item" DockPanel.Dock="Top" Command="{Binding AddMenuItem}" />
</DockPanel>
And View Model:
public class MyViewModel {
public ObservableCollection<MenuItem> DocumentExplorerMenuOptions { get; set; }
MenuItem firstMenuItem;
MenuItem secondMenuItem;
public MyViewModel() {
firstMenuItem = new MenuItem("First") { Command = new DelegatingCommand(x => MessageBox.Show("First Selected") };
secondMenuItem = new MenuItem("Second") { Command = new DelegatingCommand(x => MessageBox.Show("Second Selected") };
MenuOptions = new ObservableCollection<MenuItem> { firstMenuItem, secondMenuItem };
AddMenuItem = new DelegateCommand<object>(x => firstMenuItem.Children.Add(
new MenuItem("Child of First")));
}
public DelegateCommand<object> AddMenuItem { get; set; }
}
And class:
public class MenuItem {
public MenuItem(string text) {
Text = text;
Children = new List<MenuItem>();
}
public string Text { get; set; }
public List<MenuItem> Children { get; private set; }
public ICommand Command { get; set; }
}
Clicking the button does add the child to firstMenuItem but it does not appear in the context menu of the TextBox.
I can't figure out how to make the context menu show the dynamic content of the context menu. Any thoughts?
I would not bind to a collection of MenuItems but rather to a more data-driven collection which may contain the MenuItem header, a command which is executed upon click and another collection of such items for the sub-items. Then you could use a (Hierarchical)DataTemplate to generate the menu on the fly. Doing so would probably take care of update issues if your datatype implements the necessary interfaces.
Edit: You seem to have such a datatype already, could you post its code?
Edit2: I think the problem is that you use a style that explicitly needs to be applied (it is probably only being applied to the main context menu, not the sub-items), as noted before i'd suggest a HierarchicalDataTemplate
.
Edit3: lol...
public List<MenuItem> Children { get; private set; }
Of course it's not going to update if it's a List
and not an ObservableCollection
.
(The class is quite badly designed overall by the way, Lists should normally not even have a private setter, they should be properties with just a getter to a readonly
field)
精彩评论