您可以使用单个
DelegateCommand
实施而不是分开
ICommand
课程。
public class DelegateCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public DelegateCommand(Action<object> execute) : this(execute, null) { }
public virtual bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
有两个重载构造函数,一个只接受要执行的方法,另一个同时接受方法和
Predicate
对于
CanExecute
.
用法:
public class ViewModel
{
public ICommand DeleteProjectCommand => new DelegateCommand(DeleteProject);
private void DeleteProject(object parameter)
{
}
}
关于MVVM的进一步简化,实现属性更改通知功能的一种方法是通过以下方式:
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
internal void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后在ViewModel中:
public class ViewModel : ObservableObject
{
private object _myProperty;
public object MyProperty
{
get { return _myProperty; }
set
{
if (_myProperty != value)
{
_myProperty = value;
NotifyPropertyChanged();
}
}
}
private object _anotherProperty;
public object AnotherProperty
{
get { return _anotherProperty; }
set
{
if (_anotherProperty != value)
{
_anotherProperty = value;
NotifyPropertyChanged();
NotifyPropertyChanged("MyProperty");
}
}
}
}
请注意,在筹集资金时不需要提供财产的名称
NotifyPropertyChanged
从该属性的setter内部(感谢
[CallerMemberName]
),尽管这仍然是一种选择,例如。,
AnotherProperty
引发两个属性的更改通知。
澄清
DelegateCommand(委派命令)
适用于所有示例。传递给它的方法应具有以下签名:
void MethodName(object parameter)
这与
Execute
方法
ICommand命令
. 参数类型为
object
,因此它接受任何内容,在您的方法中,您可以将其转换为您实际传递给它的任何对象,例如:
private void AddGallery(object parameter)
{
Gallery gallery = (Gallery)parameter;
...
}
如果设置否
CommandParameter
然后
null
将被传递,因此对于另一个示例,您仍然可以使用相同的签名,只是不使用参数:
private void DeleteGallery(object parameter)
{
...
}
所以你可以使用
DelegateCommand(委派命令)
对于以上所有内容。
CanAddGallery实现
下面应该为如何实现这一点提供一个很好的模型(我发明了两个属性,
Property1
和
Property2
,代表您的
TextBox
值):
public class Gallery : ObservableObject
{
private string _property1;
public Gallery Property1
{
get { return _property1; }
set
{
if (_property1 != value)
{
_property1 = value;
NotifyPropertyChanged();
}
}
}
private Gallery _property2;
public Gallery Property2
{
get { return _property2; }
set
{
if (_property2 != value)
{
_property2 = value;
NotifyPropertyChanged();
}
}
}
public Gallery() { }
}
public class AddGalleryViewModel : ObservableObject
{
private Gallery _galleryToAdd;
public Gallery GalleryToAdd
{
get { return _galleryToAdd; }
set
{
if (_galleryToAdd != value)
{
_galleryToAdd = value;
NotifyPropertyChanged();
}
}
}
public DelegateCommand AddGalleryCommand { get; set; }
public AddGalleryViewModel()
{
AddGalleryCommand = new DelegateCommand(AddGallery, CanAddGallery)
GalleryToAdd = new Gallery();
GalleryToAdd.PropertyChanged += GalleryToAdd_PropertyChanged
}
private void AddGallery(object parameter)
{
Gallery gallery = (Gallery)parameter;
...
}
private bool CanAddGallery(object parameter)
{
Gallery gallery = (Gallery)parameter;
if (string.IsNullOrEmpty(gallery.Property1) || string.IsNullOrEmpty(gallery.Property2))
{
return false;
}
return true;
}
private void GalleryToAdd_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Property1" || e.PropertyName == "Property2")
{
AddGalleryCommand.RaiseCanExecuteChanged();
}
}
}
关于以下实施的说明:
public DelegateCommand AddGalleryCommand => new DelegateCommand(AddGallery, CanAddGallery);
我发现当我使用这种方法时
CanExecuteChanged
EventHandler
上
DelegateCommand(委派命令)
总是
无效的
,因此事件从不触发。如果
CanExecute公司
是
false
首先,按钮将始终被禁用-如果它是
true
首先,在命令执行与否方面,我仍然获得了准确的功能,但按钮始终处于启用状态。因此,我更喜欢上述示例中的方法,即:
public DelegateCommand AddGalleryCommand { get; set; }
public AddGalleryViewModel()
{
AddGalleryCommand = new DelegateCommand(AddGallery, CanAddGallery)
...
}
授权指挥专业
以下类允许您为命令参数指定类型:
public class DelegateCommand<T> : ICommand
{
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public DelegateCommand(Action<T> execute) : this(execute, null) { }
public virtual bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute((T)parameter);
}
public void Execute(object parameter)
{
_execute((T)parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
用法:
public DelegateCommand<Gallery> AddGalleryCommand { get; set; }
public AddGalleryViewModel()
{
AddGalleryCommand = new DelegateCommand<Gallery>(AddGallery, CanAddGallery)
}
private void AddGallery(Gallery gallery)
{
...
}
private bool CanAddGallery(Gallery gallery)
{
...
}
以下内容允许您指定无参数方法:
public delegate void ParameterlessAction();
public delegate bool ParameterlessPredicate();
public class InternalDelegateCommand : ICommand
{
private readonly ParameterlessPredicate _canExecute;
private readonly ParameterlessAction _execute;
public event EventHandler CanExecuteChanged;
public InternalDelegateCommand(ParameterlessAction execute) : this(execute, null) { }
public InternalDelegateCommand(ParameterlessAction execute, ParameterlessPredicate canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
用法:
public InternalDelegateCommand CreateGalleryCommand { get; set; }
public CreateGalleryViewModel()
{
CreateGalleryCommand = new InternalDelegateCommand(CreateGallery)
}
private void CreateGallery()
{
Gallery gallery = new Gallery();
...
}