2017-08-30 93 views
2

请注意:此问题与WPF - How can I create menu and submenus using binding不同,因为我想使用自己的视图模型。 MyFirstViewModel,MySecondViewModel,MyThirdViewModel不能在一种MenuItemViewModel中合并,而使用这三种视图模型的分层是我的问题,关于分层数据模板的答案对我不起作用。wpf:嵌套菜单项的绑定

我想做一个菜单,我知道我有3个关卡。

  1. 第一级是由在我的视图模型的结合到的ObservableCollection < MySecondViewModel>生成的第二电平一个静态菜单项
  2. MySecondViewModel我也有一个的ObservableCollection < MyThirdViewModel>我想结合我的第三个菜单项的水平。

在第三级我也想用一个模板,这也结合性质MyThirdViewModel的复选框。所以我的ViewModels看起来像这样:

public class MyFirstViewModel 
{ 
    public ObservableCollection<MySecondViewModel> MenuItemsSecondLevel { get; set; } 
    ... 
} 

public class MySecondViewModel 
{ 
    public string DisplayName{get; set;} 
    public ObservableCollection<MyThirdViewModel> MenuItemsThirdLevel{ get; set; } 
    ... 
} 

public class MyThirdViewModel 
{ 
    public string DisplayName{get; set;} 
    public bool IsChecked {get;set;} 
    ... 
} 

如何创建我的WPF菜单基于此?如果我试试这个:

<Menu> 
    <MenuItem Header="Select Source:" ItemsSource="{Binding MenuItemsSecondLevel}"> 
    <MenuItem Header="{Binding DisplayName}" ItemsSource="{Binding MenuItemsThirdLevel}" > 
    <MenuItem.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding DisplayName}" IsChecked="{Binding IsChecked}"/> 
     </DataTemplate> 
    </MenuItem.ItemTemplate> 
    </MenuItem> 
</MenuItem> 
</Menu> 

然后我的绑定不起作用。他无法找到任何我Collections.If的我让这样的更先进:

<Menu> 
    <MenuItem Header="Select Source:" ItemsSource="{Binding MenuItemsSecondLevel}"> 
    <MenuItem.ItemTemplate> 
     <DataTemplate> 
     <MenuItem Header="{Binding DisplayName}" ItemsSource="{Binding MenuItemsThirdLevel}" > 
      <MenuItem.ItemTemplate> 
      <DataTemplate> 
       <CheckBox Content="{Binding DisplayName}" IsChecked="{Binding IsChecked}" /> 
      </DataTemplate> 
      </MenuItem.ItemTemplate> 
     </MenuItem> 
     </DataTemplate> 
    </MenuItem.ItemTemplate> 
    </MenuItem> 
</Menu> 

他发现第二级,但不是第三。使视图模型的结构等菜单级别最好的方法是什么?

请注意,我知道你可以选择菜单项,但是我们在这里使用复选框有一个设计原因。

+0

你有没有试过通过从MenuItem中派生一个新的类来做一个自定义的'MenuItem'? – lightlike

+0

不,我没有,但你认为这会有帮助吗?这怎么能解决我的问题? – Nelly

+0

哦。抱歉。我想我误解了你的问题。你可以尝试在你的ViewModel上实现'INotifyPropertyChanged'。这可能是你在UI已经加载后设置了'ObservableCollection'。 – lightlike

回答

3

您可以使用此

<Menu> 
    <MenuItem Header="Select Source:" 
       ItemsSource="{Binding FirstViewModel.MenuItemsSecondLevel}"> 
     <MenuItem.Resources> 
      <HierarchicalDataTemplate DataType="{x:Type local:MySecondViewModel}" 
             ItemsSource="{Binding MenuItemsThirdLevel}"> 
       <TextBlock Text="{Binding DisplayName}" /> 
      </HierarchicalDataTemplate> 
      <DataTemplate DataType="{x:Type local:MyThirdViewModel}"> 
       <CheckBox Content="{Binding DisplayName}" /> 
      </DataTemplate> 
     </MenuItem.Resources> 
    </MenuItem> 
</Menu> 

假设FirstViewModel是您的视图模型的属性。

+0

哇!你让我今天一整天都感觉很好!用数据类型解决它是一个非常好的主意!这样可行! – Nelly

+0

@Nelly您的欢迎。为所有hirachical数据工作,我很容易使用:) –