如何创建遵循MVVM模式的菜单栏 以及如何将视图模型绑定到xaml
我为单个项目和菜单列表视图模型创建了项目视图模型, 收集单个项目
ItemViewModel文件
/// <summary>
/// Menu item viewModel
/// </summary>
public class MenuItemViewModel : BaseViewModel
{
#region Public Properties
/// <summary>
/// The displayed name
/// </summary>
public string Header { get; set; }
/// <summary>
/// The item order
/// </summary>
public int Order { get; set; }
/// <summary>
/// True if this item is Enabled
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// True if this item is currently selected
/// </summary>
public bool IsSelected { get; set; }
/// <summary>
/// The item icon
/// </summary>
public string Icon { get; set; }
/// <summary>
/// The parent view model.
/// </summary>
public MenuListViewModel Parent { get; set; }
#endregion
#region Public Commands
/// <summary>
/// The command for when the item is clicked
/// </summary>
public ICommand OpenCommand { get; set; }
#endregion
#region Constructor
/// <summary>
/// Default constructor
/// </summary>
public MenuItemViewModel()
{
// Create commands
OpenCommand = new RelayCommand(ItemCommand);
}
#endregion
#region Command Methods
/// <summary>
/// When the item is clicked
/// </summary>
public virtual void ItemCommand() { }
#endregion
}
MenuListViewModel文件
/// <summary>
/// Sub Menu item viewModel
/// </summary>
public class MenuListViewModel : BaseViewModel
{
#region Protected Members
/// <summary>
/// The items list
/// </summary>
protected ObservableCollection<MenuItemViewModel> mItemsChildren;
/// <summary>
/// The items list
/// </summary>
protected ObservableCollection<Action> mChildrenCommands;
/// <summary>
/// The subMenu list
/// </summary>
protected ObservableCollection<MenuListViewModel> mSubMentChildren;
#endregion
#region Public Properties
/// <summary>
/// The displayed name
/// </summary>
public string Header { get; set; }
/// <summary>
/// True if this item is Enabled
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// True if this item is currently selected
/// </summary>
public bool IsSelected { get; set; }
/// <summary>
/// The item icon
/// </summary>
public object Icon { get; set; }
/// <summary>
/// The menu order
/// </summary>
public int Order { get; set; }
/// <summary>
/// The parent view model.
/// </summary>
public MenuListViewModel ParentViewModel { get; set; }
/// <summary>
/// The items list
/// </summary>
public ObservableCollection<MenuItemViewModel> Items
{
get => mItemsChildren;
set
{
// Make sure list has changed
if (mItemsChildren == value)
return;
// Update value
mItemsChildren = value;
}
}
/// <summary>
/// The items list
/// </summary>
public ObservableCollection<Action> ItemsCommands
{
get => mChildrenCommands;
set
{
// Make sure list has changed
if (mChildrenCommands == value)
return;
// Update value
mChildrenCommands = value;
}
}
/// <summary>
/// The subMenu items for the list
/// </summary>
public ObservableCollection<MenuListViewModel> SubMenuItems
{
get => mSubMentChildren;
set
{
// Make sure list has changed
if (mSubMentChildren == value)
return;
// Update value
mSubMentChildren = value;
}
}
#endregion
public virtual void LoadChildMenuItems()
{
}
}
Xaml文件
<UserControl.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Path=Header}"/>
<Setter Property="Command" Value="{Binding Path=Command}"/>
</Style>
<HierarchicalDataTemplate
DataType="{x:Type local:MenuBarViewModel}"
ItemsSource="{Binding Path=Items}">
</HierarchicalDataTemplate>
</UserControl.Resources>
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=Items}"/>
那么如何在xaml文件中添加此viewModles并将其绑定到Headers和命令
答案 0 :(得分:0)
您的MenuItemViewModel中没有集合Items。 hierarchicaldatatemplate的工作方式是将子菜单的itemssource绑定到父菜单的属性。既然您没有,那最好的事情就是获得最高水平。
下面是一些简化的标记和代码:
<Menu ItemsSource="{Binding MenuItems}" Height="30">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Path=Header}"/>
<Setter Property="Command" Value="{Binding Path=Command}"/>
</Style>
<HierarchicalDataTemplate
DataType="{x:Type local:MenuItemVM}"
ItemsSource="{Binding SubItems}">
</HierarchicalDataTemplate>
</Menu.Resources>
</Menu>
在我的窗口viewmodel中,我设置了一些基本数据:
private ObservableCollection<MenuItemVM> menuItems = new ObservableCollection<MenuItemVM>(
new List<MenuItemVM>
{
new MenuItemVM{ Header="File", SubItems= new ObservableCollection<MenuItemVM>( new List<MenuItemVM>
{
new MenuItemVM{ Header="Open"},
new MenuItemVM{ Header="Save"}
})
}
}
);
还有我简化的menuitemvm:
public class MenuItemVM
{
public string Header { get; set; }
public ICommand Command { get; set; }
public ObservableCollection<MenuItemVM> SubItems { get; set; }
}