WPF MVVM动态子菜单绑定问题

发布于 2024-10-04 11:45:40 字数 2396 浏览 4 评论 0原文

我正在动态创建一个上下文菜单,并且菜单项有子项。 第一次出现子菜单,但第二次及之后仅显示父菜单。子子菜单位于绑定到它们只是不出现的上下文菜单的集合中。

VMMenuItems 是我的视图模型中的一个属性,

ObservableCollection<MenuItemViewModel>

每次 Listview 中的数据发生更改时,VMMenuItems 都会完全重建。 子菜单只是将另一个 MenuItemViewModel 添加到现有 MenuItemViewModel 的 Children 中。 关于如何使子菜单每次都能工作有什么想法吗?

代码

<Window.Resources>        
    <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
                              ItemsSource="{Binding Path=Children}">
        <ContentPresenter Content="{Binding Path=MenuText}" />
    </HierarchicalDataTemplate>
</Window.Resources>

 <ListView.ContextMenu>
       <ContextMenu ItemsSource="{Binding Path=VMMenuItems>
          <ContextMenu.ItemContainerStyle>
              <Style TargetType="{x:Type MenuItem}">                                    
                 <Setter Property="Command" Value="{Binding Command}"/>
                  <Setter Property="CommandParameter" Value="{Binding MenuText}"/> 
                            </Style>
                        </ContextMenu.ItemContainerStyle>
                    </ContextMenu>                       
                </ListView.ContextMenu>

public class MenuItemViewModel : ViewModel
{  
    public MenuItemViewModel()
    {
        Children = new ObservableCollection<MenuItemViewModel>();
    }


    private string _menuText;
    public string MenuText
    {

        get { return _menuText; }

        set
        {
            _menuText = value;
            OnPropertyChanged("MenuText");
        }
    }


    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }

        set
        {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");
        }
    }


    private ICommand _command;
    public ICommand Command
    {
        get { return _command; }

        set
        {
            _command = value;
            OnPropertyChanged("Command");
        }
    }

    private ObservableCollection<MenuItemViewModel> _children;
    public ObservableCollection<MenuItemViewModel> Children
    {
        get { return _children; }

        set
        {
            _children = value;
            OnPropertyChanged("Children");
        }
    }

I'm dynamically creating a context menu and the menu items have children.
The first time around the submenus appear, but on the second and there after only the parent menus show. The child submenu are in the collection that is bound to the context menu they just don't appear.

VMMenuItems is a property in my view model and is

ObservableCollection<MenuItemViewModel>

Every time the data in the Listview changes VMMenuItems is totally rebuilt.
A sub menu is just adding another MenuItemViewModel to an existing MenuItemViewModel's Children.
Any ideas as to how to make the submenus work every time?

The code

<Window.Resources>        
    <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
                              ItemsSource="{Binding Path=Children}">
        <ContentPresenter Content="{Binding Path=MenuText}" />
    </HierarchicalDataTemplate>
</Window.Resources>

 <ListView.ContextMenu>
       <ContextMenu ItemsSource="{Binding Path=VMMenuItems>
          <ContextMenu.ItemContainerStyle>
              <Style TargetType="{x:Type MenuItem}">                                    
                 <Setter Property="Command" Value="{Binding Command}"/>
                  <Setter Property="CommandParameter" Value="{Binding MenuText}"/> 
                            </Style>
                        </ContextMenu.ItemContainerStyle>
                    </ContextMenu>                       
                </ListView.ContextMenu>

public class MenuItemViewModel : ViewModel
{  
    public MenuItemViewModel()
    {
        Children = new ObservableCollection<MenuItemViewModel>();
    }


    private string _menuText;
    public string MenuText
    {

        get { return _menuText; }

        set
        {
            _menuText = value;
            OnPropertyChanged("MenuText");
        }
    }


    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }

        set
        {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");
        }
    }


    private ICommand _command;
    public ICommand Command
    {
        get { return _command; }

        set
        {
            _command = value;
            OnPropertyChanged("Command");
        }
    }

    private ObservableCollection<MenuItemViewModel> _children;
    public ObservableCollection<MenuItemViewModel> Children
    {
        get { return _children; }

        set
        {
            _children = value;
            OnPropertyChanged("Children");
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

才能让你更想念 2024-10-11 11:45:40

我必须不使用 HierarchicalDataTemplate 并将其全部放在 ContextMenu.ItemContainerStyle 中。
我不确定为什么我的其他方法不起作用(第一次有效,但其他方法不起作用)。
也许其他人可以告诉我为什么它不起作用......

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

I had to not use a HierarchicalDataTemplate and put it all here in ContextMenu.ItemContainerStyle.
I'm not sure why my other way didn't work( well it worked the 1st time but not any others).
Maybe someone else could tell me why it doesn't work...

<ContextMenu.ItemContainerStyle>
  <Style TargetType="{x:Type MenuItem}">
   <Setter Property="Header" Value="{Binding MenuText}"/>
   <Setter Property="ItemsSource" Value="{Binding Path=Children}"/>
   <Setter Property="Command" Value="{Binding Command}"/>
   <Setter Property="CommandParameter" Value="{Binding MenuText}"/>
  </Style>
 </ContextMenu.ItemContainerStyle>
罪#恶を代价 2024-10-11 11:45:40

我自己对此仍然很陌生,并且在没有测试的情况下我不确定它或确切的原因,但我相信这与用全新的系列替换儿童系列有关。我认为这需要重新绑定集合。最好从现有集合中添加/删除项目。这将触发适当的绑定通知。现在,绑定是到该集合的特定实例,该实例在 Children.set 调用中被替换。希望这有帮助。

I'm still new to this myself and I don't know for sure without testing it or exactly why, but I believe it has to do with replacing the Children collection with an entirely new collection. I think that would require rebinding the collection. It would be better for items to be added/removed from the existing collection. This would trigger the appropriate binding notifications. Right now, the binding is to a particular instance of that collection which is getting replaced on the Children.set call. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文