Я использую сервис динамического меню c в моем приложении WPF. Каждая команда может или должна иметь разные CommandParameters.
Проблема: Благодаря моему решению установить привязку CommandParamter в xaml свойство CanExecute из команды doesent update больше.
Что у меня до сих пор
Я использую 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);
}
Тогда у меня есть свойство привязки в viewmodel:
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>
Внимание. Тип привязки CommandParameter в xaml в настоящее время неверен. Это еще одна проблема, которую я решу сам. Но для целей тестирования это должно работать. Это даст мне исключение из-за неправильного типа.
Но когда я делаю привязку CommandParameter в Style.Trigger с DataTrigger, свойство CanExecute больше не обновляется во время выполнения. Когда я комментирую этот раздел, все работает отлично. Но тогда у меня нет CommandParameters.
Любая помощь и предложения приветствуются.