我有一个案例,稍微复杂一点,但我尝试说明并进行一些修改,以简单的方式说明这一点。
假设我有一个 Window1 作为视图,一个 Window1ViewModel 作为它的视图模型。我还有一个 SubMenuViewModel 类来表示窗口中的子菜单。我想在 Window1 中创建一个 ItemsControl,其中包含许多子菜单。每次用户单击其中一个子菜单时,CurrentSubMenu 属性都会更新为相应的子菜单。这就是问题所在,我无法更新Window1ViewModel中的 CurrentSubMenu 。
.
子菜单视图模型:
public class SubMenuViewModel : INPC
{
private string _submenuname;
public string SubMenuName
{
get
{ return _submenuname; }
set
{
_submenuname = value;
RaisePropertyChanged("SubMenuName");
}
}
private string _displayname;
public string DisplayName
{
get
{ return _displayname; }
set
{
_displayname = value;
RaisePropertyChanged("DisplayName");
}
}
// Command for Hyperlink in ItemsControl //
private RelayCommand _commandSubmenu;
public RelayCommand CommandSubMenu
{
get
{ return _commandSubmenu; }
set
{
_commandSubmenu = value;
RaisePropertyChanged("CommandSubMenu");
}
}
// end of command
public SubMenuViewModel(string Submenu_name, string Display_name)
{
_submenuname = Submenu_name;
_displayname = Display_name;
}
}
窗口1:
<Window x:Class="SomeProject.Window1"
xmlns:vm="clr-namespace:SomeProject.ViewModel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="This is Some Project" WindowState="Maximized">
<Window.DataContext>
<vm:Window1ViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Name="SubMenuPanelBorder"
Grid.Column="0"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="15 0 15 0"
BorderThickness="2"
BorderBrush="Black"
Padding="10 10">
<HeaderedContentControl Content="{Binding Path=SubMenus}" Header="Panel Submenu :">
<HeaderedContentControl.ContentTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding}" Foreground="White" Background="Transparent" Margin="0 15">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Command="{Binding Path=CommandSubMenu}">
<TextBlock Margin="0 5" Text="{Binding Path=DisplayName}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</HeaderedContentControl.ContentTemplate>
</HeaderedContentControl>
</Border>
.......
.......
</Grid>
</Window>
Window1ViewModel:
class Window1ViewModel : INPC
{
private List<SubMenuViewModel> _submenus;
public List<SubMenuViewModel> SubMenus
{
get
{ return _submenus; }
set
{
_submenus = value;
RaisePropertyChanged("SubMenus");
}
}
private SubMenuViewModel _currentSubMenu;
public SubMenuViewModel CurrentSubMenu
{
get
{ return _currentSubMenu; }
set
{
_currentSubMenu = value;
RaisePropertyChanged("CurrentSubMenu");
}
}
public Window1ViewModel()
{
SubMenus = MenuDefinition.GetSubMenus();
/***
Set the SubMenus's command to update the CurrentSubMenu,
and == HERE IS WHERE I GOT LOST ==.
The CurrentSubMenu is always point to the last submenu in the loop when clicked.
By the way, the reason I use loop is because the submenu in the Menu definition sometimes changed and there are many number of submenus there, and there are some other reasons (I use Menu-submenu mechanism, but it's not essential to show it here because it's not the main point I want to show). So, finally I use loop instead of specifying each command one by one.
***/
foreach(SubMenuViewModel submenu in SubMenus){
submenu.CommandSubMenu=new RelayCommand(()=>clickedSubMenu(submenu.SubMenuName));
}
}
public void clickedSubMenu(string submenu_name)
{
CurrentSubMenu = SubMenus.Find(sub => sub.SubMenuName == submenu_name);
}
}
菜单定义:
public static List<SubMenuViewModel> GetSubMenus()
{
return new List<SubMenuViewModel>
{
new SubMenuViewModel("overview_product", "Overview Products"),
new SubMenuViewModel("search_product","Search Products"),
new SubMenuViewModel("update_product","Update Data Products"),
new SubMenuViewModel("order_product","Order Products"),
new SubMenuViewModel("supplier_product","Products Supplier"),
.................
.................
.................
};
}
}