绑定到ObservableCollection <menuitem>的ContextMenu不刷新数据</menuitem>

时间:2011-02-02 16:14:19

标签: wpf mvvm

给出以下XAML片段:

<UserControl.Resources>
    <ResourceDictionary>
        <Style x:Key="ContextMenuItemStyle">
            <Setter Property="MenuItem.Header" Value="{Binding Text}"/>
            <Setter Property="MenuItem.ItemsSource" Value="{Binding 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>

并查看模型:

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; }
}

上课:

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; }
    }

单击按钮将子项添加到firstMenuItem,但它 not 出现在TextBox的上下文菜单中。

我无法弄清楚如何让上下文菜单显示上下文菜单的动态内容。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我不会绑定到MenuItems的集合,而是绑定到更多数据驱动的集合,该集合可能包含MenuItem标头,在点击时执行的命令以及子项目的此类项目的另一个集合。然后,您可以使用(Hierarchical)DataTemplate动态生成菜单。如果您的数据类型实现了必要的接口,那么这样做可能会解决更新问题。

编辑:您似乎已经有了这样的数据类型,您可以发布其代码吗?

Edit2:我认为问题在于您使用明确需要应用的样式(可能只应用于主上下文菜单,而不是子项),如上所述在我建议HierarchicalDataTemplate之前。

编辑3:哈哈......

public List<MenuItem> Children { get; private set; }

当然,如果它是List而不是ObservableCollection,则不会更新。

(顺便说一句,这个类的设计非常糟糕,列表通常不应该有私有的setter,它们应该是只有readonly字段的getter的属性