首先,我认为您应该保留代码隐藏事件处理程序,没有任何实际原因将简单的 2 行事件处理程序更改为复杂的命令驱动的怪物是没有意义的(不要说可测试性,这是主菜单,它每次运行应用程序时都会进行测试)。
现在,如果你确实想走纯 MVVM 路线,你所要做的就是让你的菜单触发一个命令,首先,在一些资源部分添加这个样式:
<Style x:Key="MenuItemStyle" TargetType="MenuItem">
<Setter Property="Command"
Value="{Binding DataContext.SwitchViewCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}"/>
<Setter Property="CommandParameter"
Value="{Binding}"/>
</Style>
此样式将使菜单项在附加的视图模型上触发 SwitchViewCommand,并将 MenuItem 的 DataContext 作为命令参数。
实际视图与您的代码相同,只是将该样式作为 ItemContainerStyle 的附加引用(因此它适用于菜单项而不是 DataTemplate 的内容):
<DockPanel LastChildFill="False">
<Menu DockPanel.Dock="Top"
ItemsSource="{Binding PageItemsMainMenu}"
ItemTemplate="{StaticResource MainMenuStyle}"
ItemContainerStyle="{StaticResource MenuItemStyle}"/>
<ContentControl
Content="{Binding SelectedPageItem}"/>
</DockPanel>
现在在您需要的视图模型中(我使用字符串,因为我没有您的 PageItem 代码):
private string _selectedViewItem;
public List<string> PageItemsMainMenu { get; set; }
public string SelectedPageItem
{
get { return _selectedViewItem; }
set { _selectedViewItem = value; OnNotifyPropertyChanged("SelectedPageItem"); }
}
public ICommand SwitchViewCommand { get; set; }
并使用您使用的任何命令类使命令调用此代码:
private void DoSwitchViewCommand(object parameter)
{
SelectedPageItem = (string)parameter;
}
现在,当用户单击菜单项时,菜单项将调用 SwitchViewCommand,并将页面项作为参数。
该命令将调用将设置 SelectedPageItem 属性的 DoSwitchViewCommand
该属性将引发 NotifyPropertyChanged,这将使 UI 通过数据绑定进行更新。
或者,您可以编写一个 2 行事件处理程序,由您选择