我有一个场景,需要同时拥有静态和动态菜单项。静态项目将在XAML中定义,而动态项目则由视图模型提供。每个动态项目本身将由一个视图模型表示,我们称之为CommandViewModel。
CommandViewModel除其他内容外,还具有显示名称,并且可以包含其他CommandViewModels。
用作菜单数据上下文的MainViewModel如下:
public class MainMenuViewModel : INotifyPropertyChanged
{
private ObservableCollection<CommandViewModel> m_CommandVMList;
public MainMenuViewModel()
{
m_ CommandVMList = new ObservableCollection<CommandViewModel>();
CommandViewModel cmv = new CommandViewModel();
cmv.DisplayName = "Dynamic Menu 1";
m_CommandVMList.Add(cmv);
cmv = new CommandViewModel();
cmv.DisplayName = "Dynamic Menu 2";
m_CommandVMList.Add(cmv);
cmv = new CommandViewModel();
cmv.DisplayName = "Dynamic Menu 3";
m_CommandVMList.Add(cmv);
}
public ObservableCollection<CommandViewModel> CommandList
{
get { return m_CommandVMList; }
set
{
m_CommandVMList = value;
OnPropertyChanged("CommandList");
}
}
菜单的XAML代码:
<Grid>
<Grid.Resources>
<HierarchicalDataTemplate DataType="{x:Type Fwf:CommandViewModel}" ItemsSource="{Binding Path=CommandViewModels}">
<MenuItem Header="{Binding Path=DisplayName}"/>
</HierarchicalDataTemplate>
</Grid.Resources>
<Menu VerticalAlignment="Top" HorizontalAlignment="Stretch">
<MenuItem Header="Static Top Menu Item 1">
<MenuItem Header="Static Menu Item 1"/>
<MenuItem Header="Static Menu Item 2"/>
<MenuItem Header="Static Menu Item 3"/>
<ItemsControl ItemsSource="{Binding Path= CommandList}"/>
<MenuItem Header="Static Menu Item 4"/>
</MenuItem>
</Menu>
</Grid>
除了一个问题,所有东西都很好,就是无论我尝试如何表示动态菜单列表,比如使用ItemsControl,在UI上它都会显示为一个菜单项包含更多的菜单项,所以当你点击这个项目时,整个动态菜单项集合都会被选中。该集合在表示上是正确的,因为每个动态菜单项本身都显示为一个菜单项,但在这个更大的菜单项内部。我认为我知道原因了,因为菜单只是为其中包含的每个项(静态或动态)创建菜单项,而不关心它们的类型。是否有一种方法可以使每个动态菜单项在示例中与静态菜单项一样属于父菜单项并在同一级别上创建?