我有这个代码:
public ICommand ChangePageCommand
{
get
{
if (this.changePageCommand == null)
{
this.changePageCommand = new ActionCommand(
parameter => {
this.ChangeViewModel((IPageViewModel)parameter);
},
parameter => parameter is IPageViewModel);
}
return this.changePageCommand;
}
}
每当我调用这个特定命令时
IPageViewModel
实现类,第二个参数
ActionCommand
在字典里。这是我的整个ViewModel类:
using VexLibrary.Windows;
using System.Windows.Input;
using System.Collections.Generic;
using VexLibrary.DesktopClient.ViewModels;
using System.Linq;
namespace VexLibrary.DesktopClient.ViewModels
{
class ApplicationViewModel : ViewModel
{
private ICommand changePageCommand;
private IPageViewModel currentPageViewModel;
private Dictionary<string, IPageViewModel> pageViewModels;
public ApplicationViewModel()
{
this.PageViewModels.Add("Dashboard", new DashboardViewModel(this));
this.PageViewModels.Add("Statistics", new StatisticsViewModel());
this.CurrentPageViewModel = this.PageViewModels["Dashboard"];
}
public ICommand ChangePageCommand
{
get
{
if (this.changePageCommand == null)
{
this.changePageCommand = new ActionCommand(
parameter => {
this.ChangeViewModel((IPageViewModel)parameter);
},
parameter => parameter is IPageViewModel);
}
return this.changePageCommand;
}
}
public IPageViewModel CurrentPageViewModel
{
get
{
return this.currentPageViewModel;
}
set
{
if (this.currentPageViewModel != value)
{
this.currentPageViewModel = value;
NotifyPropertyChanged();
}
}
}
public Dictionary<string, IPageViewModel> PageViewModels
{
get
{
if (this.pageViewModels == null)
this.pageViewModels = new Dictionary<string, IPageViewModel>();
return this.pageViewModels;
}
}
public void ChangeViewModel(IPageViewModel viewModel)
{
this.CurrentPageViewModel = this.pageViewModels.FirstOrDefault(element => element.Value == viewModel).Value;
}
}
}
出于某种原因,尽管参数实现了
IPageViewModel
,它总是导致错误。这是我的
行动命令
类别:
using System;
using System.Windows.Input;
namespace VexLibrary.Windows
{
public sealed class ActionCommand : ICommand
{
private readonly Action<Object> action;
private readonly Predicate<Object> predicate;
public event EventHandler CanExecuteChanged;
/// <summary>
/// Initializes a new instance of the <see cref="ActionCommand"/> class.
/// </summary>
/// <param name="action">The <see cref="Action"/> delegate to wrap.</param>
public ActionCommand(Action<Object> action) : this(action, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ActionCommand"/> class.
/// </summary>
/// <param name="action">The <see cref="Action"/> delegate to wrap.</param>
/// <param name="predicate">The <see cref="Predicate{Object}"/> that determines whether the action delegate may be invoked.</param>
public ActionCommand(Action<Object> action, Predicate<Object> predicate)
{
if (action == null)
{
throw new ArgumentNullException("action", "You must specify an Action<T>.");
}
this.action = action;
this.predicate = predicate;
}
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public bool CanExecute(object parameter)
{
if (predicate == null)
{
return true;
}
return predicate(parameter);
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public void Execute(object parameter)
{
action(parameter);
}
/// <summary>
/// Executes the action delegate without any parameters.
/// </summary>
public void Execute()
{
Execute(null);
}
}
}
下面是一个用例:
<Button Command="{Binding ChangePageCommand}" CommandParameter="{Binding PageViewModels[Dashboard]}">
<TextBlock Style="{StaticResource TitleBarIcon}" Text="" />
</Button>
这里的问题是,
CanExecute
始终计算为false,因此,此处的按钮单击是禁用的。但是,我尝试将谓词替换为
true
这使得程序完全按照预期工作。这里是DashboardViewModel,这是我在这里传递给命令的:
using VexLibrary.Windows;
using System.Windows.Input;
namespace VexLibrary.DesktopClient.ViewModels
{
class DashboardViewModel : ViewModel, IPageViewModel
{
private string name = "Dashboard";
private ApplicationViewModel parentViewModel;
private ICommand statisticsPageCommand;
public DashboardViewModel(ApplicationViewModel parentViewModel)
{
this.parentViewModel = parentViewModel;
}
public ICommand StatisticsPageCommand
{
get
{
return new ActionCommand(
parameter => this.parentViewModel.ChangeViewModel(this.parentViewModel.PageViewModels["Statistics"])
);
}
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
NotifyPropertyChanged();
}
}
}
}