属性绑定到ObservableCollection更改时如何通知ViewModel?

时间:2019-05-18 05:37:34

标签: c# wpf xaml mvvm

我正在使用HierarchicalDataTemplate构建菜单栏,该菜单栏将具有可检查的MenuItem。在我的ViewModel中,我创建一个名为MenuItemModel的类的ObservableCollection,然后将ObservableCollection绑定到我的View中。我可以构建菜单及其子菜单,但是我不知道如何告诉ViewModel选中了哪个MenuItem。

我尝试在MenuItemModel中使用INotifyPropertyChanged,但是我不知道如何将信息发送到ViewModel。经过大量的搜索之后,我得出的结论是这不是正确的方法,我只需要在ViewModel中使用INotifyPropertyChanged。我是WPF的新手,因此仍在学习该做什么和不该做什么。我在StackOverflow上找到了下面的大多数代码,并设法使其适应了我的需求,但我仍在努力探索其工作原理。下面的代码将创建一个带有三个子菜单“ SubMenu1”,“ SubMenu2”和“ SubMenu3”的菜单“ Main Menu”,在这些菜单中都可以对其进行检查。话虽如此,这是我的问题:

  1. 当MenuItem被选中/未选中时,如何/在何处在ViewModel中实现OnPropertyChanged事件?
  2. 如何访问已选中/未选中的MenuItem的模型属性?
            <Menu DockPanel.Dock="Top" ItemsSource="{Binding MenuItemsObservableCollection}">
                <Menu.ItemContainerStyle>
                    <Style TargetType="{x:Type MenuItem}">
                        <Setter Property="IsCheckable"  Value="{Binding IsCheckable}" />
                        <Setter Property="StaysOpenOnClick"  Value="{Binding IsCheckable}" />
                        <Setter Property="IsChecked"  Value="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                    </Style>
                </Menu.ItemContainerStyle>
                <Menu.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type local:ViewModel}" ItemsSource="{Binding Path=SubMenuItemsObservableCollection}">
                        <TextBlock Text="{Binding Header}"/>
                    </HierarchicalDataTemplate>
                </Menu.ItemTemplate>
            </Menu>
    class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
            AddMenuItems();
        }

        private void AddMenuItems()
        {
            var subMenu = new ObservableCollection<MenuItemModel>
            {
                new MenuItemModel { Header = "SubMenu1" },
                new MenuItemModel { Header = "SubMenu2"},
                new MenuItemModel { Header = "SubMenu3"}
            };            

            MenuItemsObservableCollection = new ObservableCollection<MenuItemModel>
            {
                new MenuItemModel { Header = "Main Menu", SubMenuItemsObservableCollection = subMenu }
            };
        }

        private void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<MenuItemModel> MenuItemsObservableCollection { get; set; }



    }
class MenuItemModel
    {
        public MenuItemModel()
        {
        }

        public string Header { get; set; }
        public string Key { get; set; }
        public bool IsCheckable { get; set; } = true
        public bool IsChecked { get; set; } = false;

        public ObservableCollection<MenuItemModel> SubMenuItemsObservableCollection { get; set; }
    }

0 个答案:

没有答案