我有一个案例,稍微复杂一点,但我尝试说明并做一些修改以简单的方式说明问题所在。
假设我有一个Window1作为 View ,一个Window1ViewModel作为它的 View 模型。我还有一个SubMenuViewModel类来表示窗口中的子菜单。我想在包含许多子菜单的Window1中创建一个ItemsControl。每次用户单击子菜单之一时,属性CurrentSubMenu都会更新为相应的子菜单。这是问题,我无法在Window1ViewModel中更新CurrentSubMenu。
。
SubMenuViewModel:
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"),
.................
.................
.................
};
}
}
最佳答案
我相信您的绑定(bind)属性应这样写。
private string _Terminal;
public string Terminal
{
get
{
return _Terminal;
}
set
{
_Terminal = value;
OnPropertyChanged("Terminal");
}
}
确保viewmodel实现INotifyPropertyChanged
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
propertyChanged(this, e);
}
}
关于c# - WPF MVVM案例: ItemsControl contains hyperlink and command to update property in ViewModel,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19148850/