苦苦研究了好长时间,终于搞定mvvm 框架下的 menu 绑定,包括二层和三层MenuItem及其Header、Command和 CommandParameter的绑定,真是好难。
主程序 MainViewModel.cs
public class MainViewModel : ViewModelBase
{
public RelayCommand LoginCommand { get; set; }
public RelayCommand LogoutCommand { get; set; }
public RelayCommand AboutCommand { get; set; }
public RelayCommand QuitWindowCommand { get; set; }
public RelayCommand NewWindowCommand { get; set; }
public RootMenuViewModel TheMenuA { get; set; }
public RootMenuViewModel TheMenuB { get; set; }
public MainViewModel()
{
LoginCommand = new RelayCommand(DoLogin);
AboutCommand = new RelayCommand(DoAbout);
LogoutCommand = new RelayCommand(DoLogout, CanDoLogout);
NewWindowCommand = new RelayCommand(DoNewWindow, CanDoNewWindow);
QuitWindowCommand = new RelayCommand(DoQuit);
TheMenuA = GetMenusA();
TheMenuB = GetMenusB();
TheMenuC = GetMenusC();
}
private RootMenuViewModel GetMenusA()
{
RootMenu RootMenuA = new RootMenu("文件");
RootMenuA.MenuItems = new List
相关菜单类字段属性:
public class RootMenu
{
public string RootName { get; set; }
public RelayCommand Command { get; set; }
public List MenuItems { get; set; }
public RootMenu(string rootName) { RootName = rootName; }
}
public class MenuItem
{
public string MenuItemName { get; set; }
public RelayCommand Command { get; set; }
public List Childs { get; set; }
public MenuItem(string menuName, RelayCommand command) { MenuItemName = menuName; Command = command; }
public MenuItem(string menuName) { MenuItemName = menuName; }
public MenuItem() { }
}
public class ChildItem
{
public string ChildName { get; set; }
public short Childlx { get; set; }
public RelayCommand Command { get; set; }
public MenuItem MenuItem { get; set; }
public ChildItem(MenuItem menuClass, string childName, short childlx, RelayCommand command) { MenuItem = menuClass; ChildName = childName; Childlx = childlx; Command = command; }
public ChildItem() { }
}
public class SeparatorViewModel : MenuItemViewModel
{
public SeparatorViewModel(MenuItemViewModel parentViewModel)
: base(parentViewModel)
{
}
}
public class MenuItemViewModel : ViewModelBase
{
///
/// Initializes a new instance of the class.
///
/// The parent view model.
public MenuItemViewModel(MenuItemViewModel parentViewModel)
{
ParentViewModel = parentViewModel;
_childMenuItems = new ObservableCollection();
}
private ObservableCollection _childMenuItems;
///
/// Gets the child menu items.
///
/// The child menu items.
public ObservableCollection Children
{
get
{
return _childMenuItems;
}
}
private string _header;
///
/// Gets or sets the header.
///
/// The header.
public string Header
{
get
{
return _header;
}
set
{
_header = value; RaisePropertyChanged("Header");
}
}
private short _childlx;
///
/// Gets or sets the CommandParameter.
///
/// The CommandParameter.
public short Childlx
{
get
{
return _childlx;
}
set
{
_childlx = value; RaisePropertyChanged("Childlx");
}
}
///
/// Gets or sets the Command.
///
/// The Command.
private RelayCommand command;
public RelayCommand Command
{
get
{
return command;
}
set
{
command = value; RaisePropertyChanged("Command");
}
}
///
/// Gets or sets the parent view model.
///
/// The parent view model.
public MenuItemViewModel ParentViewModel { get; set; }
public virtual void LoadChildMenuItems()
{
}
Root菜单类:
public class RootMenuViewModel : MenuItemViewModel
{
private RootMenu _rootMenu;
///
/// Initializes a new instance of the class.
///
/// The parent view model.
public RootMenuViewModel(RootMenu rootMenu)
: base(null)
{
_rootMenu = rootMenu;
base.Header = RootName;
base.Command = RootCommand;
if (_rootMenu.MenuItems != null)
LoadChildMenuItems();
}
public string RootName
{
get
{
return _rootMenu.RootName;
}
set
{
_rootMenu.RootName = value; RaisePropertyChanged("RootName");
}
}
public RelayCommand RootCommand
{
get
{
return _rootMenu.Command;
}
set
{
_rootMenu.Command = value; RaisePropertyChanged("RootCommand");
}
}
///
/// Loads the child menu items.
///
public override void LoadChildMenuItems()
{
_rootMenu.MenuItems.ForEach
(
MenuItem =>
{
if (MenuItem.MenuItemName == string.Empty || MenuItem.MenuItemName == "Separator")
{
SeparatorViewModel separatorViewModel = new SeparatorViewModel(this);
Children.Add(separatorViewModel);
}
else if (MenuItem.MenuItemName != null)
{
MenuClassViewModel childMenuViewModel = new MenuClassViewModel(this, MenuItem);
childMenuViewModel.Header = MenuItem.MenuItemName;
childMenuViewModel.Command = MenuItem.Command;
Children.Add(childMenuViewModel);
}
}
);
}
public class MenuClassViewModel : MenuItemViewModel
{
private MenuItem _menuClass;
///
/// Initializes a new instance of the class.
///
/// The parent view model.
public MenuClassViewModel(RootMenuViewModel parentViewModel, MenuItem menuClass)
: base(parentViewModel)
{
_menuClass = menuClass;
if (_menuClass.Childs != null)
LoadChildMenuItems();
}
//private string _menuName;
///
/// Gets or sets the name of the team.
///
/// The name of the team.
public string MenuName
{
get
{
return _menuClass.MenuItemName;
}
set
{
_menuClass.MenuItemName = value; RaisePropertyChanged("MenuName");
}
}
public RelayCommand ItemCommand
{
get
{
return _menuClass.Command;
}
set
{
_menuClass.Command = value; RaisePropertyChanged("ItemCommand");
}
}
public override void LoadChildMenuItems()
{
_menuClass.Childs.ForEach(child =>
{
if (child.ChildName == string.Empty)
{
SeparatorViewModel separatorViewModel = new SeparatorViewModel(this);
Children.Add(separatorViewModel);
}
else
{
ChildMenuViewModel childViewModel = new ChildMenuViewModel(this, child);
childViewModel.Header = child.ChildName;
childViewModel.Childlx = child.Childlx;
childViewModel.Command = child.Command;
Children.Add(childViewModel);
}
});
}
}
class ChildMenuViewModel : MenuItemViewModel
{
private ChildItem _child;
///
/// Initializes a new instance of the class.
///
/// The parent view model.
public ChildMenuViewModel(MenuClassViewModel parentViewModel, ChildItem child)
: base(parentViewModel)
{
_child = child;
}
public string ChildName
{
get
{
return _child.ChildName;
}
set
{
_child.ChildName = value; RaisePropertyChanged("ChildName");
}
}
public short ChildLx
{
get
{
return _child.Childlx;
}
set
{
_child.Childlx = value; RaisePropertyChanged("ChildLx");
}
}
public RelayCommand ChildCommand
{
get
{
return _child.Command;
}
set
{
_child.Command = value; RaisePropertyChanged("ChildCommand");
}
}
}