通用/类型安全的ICommand实现?

Ale*_*nor 11 c# generics wpf .net-4.0 mvvm

我最近开始使用WPF和MVVM框架,我想做的一件事就是有一个类型安全的实现,ICommand所以我不必抛出所有的命令参数.

有谁知道这样做的方法?

use*_*116 14

你没有使用那种语法,你可能会发现:

错误CS0701:``System.Func`'不是有效约束.约束必须是接口,非密封类或类型参数

最好的办法是将Func<E,bool>语义封装在一个界面中,例如:

interface IFunctor<E>
{
   bool Execute(E value);
}
Run Code Online (Sandbox Code Playgroud)

然后在类定义中使用此接口.虽然,我想知道你想要完成什么,因为可能有另一种方法来解决你的问题.

根据@Alex寻找强类型ICommand实现的评论:

public FuncCommand<TParameter> : Command
{
    private Predicate<TParameter> canExecute;
    private Action<TParameter> execute;

    public FuncCommand(Predicate<TParameter> canExecute, Action<TParameter> execute)
    {
        this.canExecute = canExecute;
        this.execute = execute;
    }

    public override bool CanExecute(object parameter)
    {
        if (this.canExecute == null) return true;

        return this.canExecute((TParameter)parameter);
    }

    public override void Execute(object parameter)
    {
        this.execute((TParameter)parameter);
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

public class OtherViewModel : ViewModelBase
{
    public string Name { get; set; }
    public OtherViewModel(string name) { this.Name = name; }
}

public class MyViewModel : ViewModelBase
{
    public ObservableCollection<OtherViewModel> Items { get; private set; }
    public ICommand AddCommand { get; private set; }
    public ICommand RemoveCommand { get; private set; }

    public MyViewModel()
    {
        this.Items = new ObservableCollection<OtherViewModel>();

        this.AddCommand = new FuncCommand<string>(
            (name) => !String.IsNullOrEmpty(name),
            (name) => this.Items.Add(new OtherViewModel(name)));
        this.RemoveCommand = new FuncCommand<OtherViewModel>(
            (vm) => vm != null,
            (vm) => this.Items.Remove(vm));
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<ListBox x:Name="Items" ItemsSource="{Binding Items}" />
<Button Content="Remove"
        Command="{Binding RemoveCommand}"
        CommandParameter="{Binding SelectedItem, ElementName=Items}" />
<StackPanel Orientation="Horizontal">
    <TextBox x:Name="NewName" />
    <Button Content="Add"
            Command="{Binding AddCommand}"
            CommandParameter="{Binding Text, ElementName=NewName}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

我建议使用Microsoft的DelegateCommandRelayCommand,或其中任何一个的任何其他实现.

  • 他确实说过MVVM框架.我想知道他使用的框架还没有这个. (2认同)