WPF MVVM中如何单行声明ICommand以减少重复代码?
解决WPF MVVM中单行声明ICommand的问题
你遇到的错误是因为字段初始化器的执行时机早于类构造函数,此时类的实例成员(比如DeleteCustomerAction这类非静态方法)还未完成初始化,所以无法直接在字段初始化时引用它们。下面提供几种可行的简化写法,帮你减少重复代码:
方案1:表达式体属性(懒加载,与原有逻辑一致)
用表达式体属性替代传统的属性+私有字段写法,既保持简洁,也能按需创建命令。如果要确保命令只被创建一次,可以结合Lazy<T>:
// 基础版(每次访问都会创建新的RelayCommand,适合无状态命令) public ICommand CommandDeleteCustomer => new RelayCommand<object>(DeleteCustomerAction, DeleteCustomerPredicate); // 确保只创建一次的版本 private readonly Lazy<ICommand> _commandDeleteCustomer = new Lazy<ICommand>(() => new RelayCommand<object>(DeleteCustomerAction, DeleteCustomerPredicate)); public ICommand CommandDeleteCustomer => _commandDeleteCustomer.Value;
方案2:构造函数初始化readonly字段
将readonly字段的初始化移到构造函数中,此时实例已创建,可以正常引用实例方法:
public readonly ICommand CommandDeleteCustomer; public vmCustomers() { CommandDeleteCustomer = new RelayCommand<object>(DeleteCustomerAction, DeleteCustomerPredicate); }
方案3:内联业务逻辑到Lambda
如果命令的业务逻辑简单,直接把逻辑写在Lambda表达式里,就能直接用字段初始化:
public readonly ICommand CommandDeleteCustomer = new RelayCommand<object>( obj => { // 直接写DeleteCustomerAction的业务逻辑 ...stuff... }, obj => { // 直接写DeleteCustomerPredicate的逻辑 ...stuff... return true; } );
方案4:利用RelayCommand的无参数重载(如果支持)
如果你的RelayCommand实现了无参数的委托重载,可以进一步简化:
public ICommand CommandDeleteCustomer => new RelayCommand(DeleteCustomerAction, DeleteCustomerPredicate);
以上几种方式都能帮你减少命令声明的重复代码,专注于业务逻辑的实现。
内容的提问来源于stack exchange,提问作者Mark Roworth
相关产品推荐
相关产品推荐

