C# WPF在单行中声明ICommand

wz3gfoph  于 2022-11-18  发布在  C#
关注(0)|答案(2)|浏览(138)

我正在学习WPF和MVVM设计模式。目前,我的ViewModel中删除客户命令的代码如下所示:

public class vmCustomers : INotifyPropertyChanged
    {
...
        private ICommand _commandDeleteCustomer = null;
...
        public ICommand CommandDeleteCustomer
        {
            get
            {
                if (_commandDeleteCustomer == null)
                    _commandDeleteCustomer = new RelayCommand<object>(DeleteCustomerAction, DeleteCustomerPredicate);
                return _commandDeleteCustomer;
            }
        }

        private void DeleteCustomerAction(object o)
        {
            ...stuff...
        }

        private bool DeleteCustomerPredicate(object o)
        {
            ...stuff...
            return true;
        }
    }

我希望将ICommand的声明精简为如下形式,以便减少每个命令的编码开销:

public readonly ICommand CommandDeleteCustomer = new RelayCommand((obj) => DeleteCustomerAction(obj), (obj) => DeleteCustomerPredicate(obj));

但我得到这个错误:
A field initializer cannot reference the non-static field, method, or property vmCustomers.DeleteCustomerAction(object)
是否有一种方法可以在一行代码中声明ICommand,这样我就可以简单地关注与业务相关的代码,而不是重复的基础结构代码。

xe55xuns

xe55xuns1#

如果您的RelayCommand.CanExecuteChanegd挂接到CommandManager.RequerySuggested事件,则可以删除构造函数初始化,并在单行语句中将该属性初始化为只读计算属性:

// Creates a *new instance* on every Get() access
public ICommand CommandDeleteCustomer => new RelayCommand(...);

// The following is the verbose form of the previous single line property declaration:
public ICommand CommandDeleteCustomer
{
  get => new RelayCommand(...);
}

若要确保从属性返回 * 相同的示例 *,请使用
a)null合并指派运算子(C# 8.0)

// Backing field required 
private ICommand commandDeleteCustomer;
public ICommand CommandDeleteCustomer => this.commandDeleteCustomer ??= new RelayCommand(...);

// The following is the verbose form of the previous property declaration
// and uses the null coalescing operator:
public ICommand CommandDeleteCustomer => this.commandDeleteCustomer = this.commandDeleteCustomer ?? new RelayCommand(...);

B)属性初始化器(单行语句):

// Returns the *same instance* on every Get() access.
// Note that you can't reference instance members like fields and properties from the initializer. 
// This means the command delegates would have to be defined as 'private static'.
public ICommand CommandDeleteCustomer { get; } = new RelayCommand<object>(DeleteCustomerAction, DeleteCustomerPredicate);

private static void DeleteCustomerAction(object o)
{
  ...stuff...
}

private static bool DeleteCustomerPredicate(object o)
{
  ...stuff...
  return true;
}
bqf10yzr

bqf10yzr2#

宣告只读的自动实作属性

public ICommand CommandDeleteCustomer { get; }

并将初始化语句移到视图模型构造函数中

public VmCustomers()
{
    CommandDeleteCustomer = new RelayCommand(...);
}

相关问题