我在我的 WPF 应用程序中实现了一个动态菜单服务。每个命令可以或应该有不同的命令参数。
问题: 使用我在 xaml 中设置 CommandParamter 绑定的解决方案,命令中的 CanExecute 属性不再更新。
到目前为止我有什么
我正在使用 mvvm-light 和 fody-propertychanged。
这里的菜单类:
public class MyMenu : INotifyPropertyChanged
{
private ObservableCollection<MyMenu> myChildren;
public MyMenu()
{
myChildren = new ObservableCollection<MyMenu>();
}
public string Header { get; set; }
public string Image { get; set; }
public string CommandName { get; set; } //used to set the CommandParameter binding
public ICommand Command { get; set; }
public ObservableCollection<MyMenu> Children {
get
{
return myChildren;
}
private set
{
myChildren = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
此类由 MenuService 使用:
public sealed class MenuService : INotifyPropertyChanged
{
private static readonly Lazy<MenuService> lazy = new Lazy<MenuService>(() => new MenuService());
public static MenuService Instance { get { return lazy.Value; } }
private ObservableCollection<MyMenu> myMainMenu;
public event PropertyChangedEventHandler PropertyChanged;
private MenuService()
{
myMainMenu = new ObservableCollection<MyMenu>();
}
public ObservableCollection<MyMenu> MainMenu
{
get
{
return myMainMenu;
}
private set
{
myMainMenu = value;
}
}
}
在视图模型的构造函数中,我得到了 MenuService 的实例并添加了一些项目:
private void AddMenuItems()
{
MyMenu OpenUserLoginMenuItem = new MyMenu
{
Header = "_Login",
Image = "./Icons/IconLogin.png",
Command = OpenSelectTestprocedureWindowCommand,
CommandName = "OpenUserLoginDialogCommand"
};
MyMenu OpenSelectTestprocedureMenuItem = new MyMenu
{
Header = "_Select Testprocedure",
Image = "./Icons/IconSelectTestprocedure.png",
Command = OpenSelectTestprocedureWindowCommand,
CommandName = "OpenSelectTestprocedureWindowCommand"
};
MainMenu.Add(OpenUserLoginMenuItem);
MainMenu.Add(OpenSelectTestprocedureMenuItem);
}
然后我在视图模型中有一个可绑定的属性:
public ObservableCollection<MyMenu> MainMenu
{
get
{
return myMenuService.MainMenu;
}
}
这里的命令实现为 RelayCommand:
//in the constructor
OpenSelectTestprocedureWindowCommand = new RelayCommand<ShowTestschrittViewParameter>(OpenSelectTestablaufWindow, CanOpenSelectTestablaufWindow);
OpenUserLoginDialogCommand = new RelayCommand<Type>(OpenUserLoginDialog);
private void OpenUserLoginDialog(Type aWindowType)
{
myNavigationService.ShowWindowModal(aWindowType);
}
private bool CanOpenSelectTestablaufWindow(ShowTestschrittViewParameter showTestschrittViewParameter)
{
if (myDataService.CurrentTestProcedure != null)
{
if (myDataService.CurrentTestProcedure.TestProcedureState == Logic.Model.GlobalTypes.TestProcedureState.Running) return false;
}
return new ViewModelLocator().UserLoginDialogViewModel.User.NameIsValid;
}
private void OpenSelectTestablaufWindow(ShowTestschrittViewParameter showTestschrittViewParameter)
{
myNavigationService.ShowTestschrittView(showTestschrittViewParameter);
}
然后在 MainView 我有以下 xaml:
<Menu Grid.Row="2" ItemsSource="{Binding MainMenu}" Name="DynamicMenu">
<!--<Menu.ItemTemplate>
<DataTemplate DataType="{x:Type luih:MyMenu}">
<StackPanel>
<Label Content="{Binding Header}"/>
<Image Source="{Binding Image}"/>
</StackPanel>
</DataTemplate>
</Menu.ItemTemplate>-->
<Menu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="ItemsSource" Value="{Binding Children}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CommandName}" Value="OpenUserLoginDialogCommand">
<Setter Property="CommandParameter" Value="{x:Type local:UserLoginDialog}"/>
</DataTrigger>
<DataTrigger Binding="{Binding CommandName}" Value="OpenSelectTestprocedureWindowCommand">
<Setter Property="CommandParameter" Value="{x:Type local:UserLoginDialog}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
注意力。xaml 中的 CommandParameter 绑定类型当前不正确。这是另一个问题,我会自己解决。但出于测试目的,它应该可以工作。由于类型错误,它会给我一个例外。
但是,当我在 Style.Trigger 中使用 DataTrigger 进行 CommandParameter 绑定时,CanExecute 属性在运行时不再更新。当我将此部分注释掉时,一切正常。但是我没有CommandParameters。
欢迎任何帮助和建议。