我想在textbox属性文本不为null时启用RibbonButton。当textbox属性文本为null时,禁用RibbonButton。我想在ICommand中使用CanExecute方法。我该怎么办?
查看:
<Custom:RibbonButton
LargeImageSource="..\Shared\img\save_diskete.png"
Label="Save"
Command="{Binding ButtonCommand}">
</Custom:RibbonButton>
视图模型
class KomentarViewModel:BaseViewModel
{
#region Data
private ICommand m_ButtonCommand;
public ICommand ButtonCommand
{
get
{
return m_ButtonCommand;
}
set
{
m_ButtonCommand = value;
}
}
private string textKomentar;
public string TextKomentar
{
get
{
return this.textKomentar;
}
set
{
// Implement with property changed handling for INotifyPropertyChanged
if (!string.Equals(this.textKomentar, value))
{
textKomentar = value;
OnPropertyChanged("TextKomentar");
}
}
}
private ObservableCollection<Komentar> allCommentsInc;
public ObservableCollection<Komentar> AllCommentsInc
{
get
{
return allCommentsInc;
}
set
{
allCommentsInc = value;
OnPropertyChanged("AllCommentsInc");
}
}
public int idIncident { get; private set; }
public Incident incident { get; private set; }
#endregion
#region Constructor
public KomentarViewModel(int id)
{
CC_RK2Entities context = new CC_RK2Entities();
this.idIncident = id;
AllCommentsInc = new ObservableCollection<Komentar>(context.Komentar.Where(a => a.Incident_id == idIncident));
incident = context.Incident.Where(a => a.id == idIncident).First();
//ButtonCommand = new RelayCommand(new Action<object>(ShowMessage));
}
#endregion
#region Methods
//ukaz napsany text
public void ShowMessage(object obj)
{
//MessageBox.Show(obj.ToString());
MessageBox.Show(this.TextKomentar);
}
}
RelayCommand
namespace Admin.Shared.Commands
{
class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
}
答案 0 :(得分:11)
您需要像这样修改您的RelayCommand类
class RelayCommand : ICommand
{
private Action<object> _action;
private Func<bool> _func;
public RelayCommand(Action<object> action,Func<bool> func)
{
_action = action;
_func = func;
}
public void RaiseCanExecuteChanged()
{
if(CanExecuteChanged!=null)
CanExecuteChanged(this,new EventArgs());
}
#region ICommand Members
public bool CanExecute(object parameter)
{
if (_func != null)
return _func();
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
将ButtonCommand初始化为
ButtonCommand = new RelayCommand((s) => ShowMessage(s),()=>!string.IsNullOrEmpty(TextKomentar));
从Text属性
的setter中获取RaiseCanExcuteChanged public string TextKomentar
{
get
{
return this.textKomentar;
}
set
{
// Implement with property changed handling for INotifyPropertyChanged
if (!string.Equals(this.textKomentar, value))
{
textKomentar = value;
OnPropertyChanged("TextKomentar");
}
ButtonCommand.RaiseCanExecuteChanged();
}
}
答案 1 :(得分:3)
为canexecute实现这个:
function catupload($results_array)
{
$this->db->insert('cr_main_shop_type', $results_array);
}
因为public bool CanExecute(object parameter)
{if(thistext available)
return true;
else
return false;
}
的{{1}}方法发生变化时会引发CanExecuteChanged
。当一些可能改变CanExecute
的命令时,它会被调用。
并且可以执行更改应该更改为:
ICommand
修改强>
在视图模型构造函数中:
canexecute
这样做。
答案 2 :(得分:1)
简单地说,您需要满足以下条件:
delegate
命令:public class DelegateCommand : DelegateCommandBase
{
private Action _executeMethod;
private Func<bool> _canExecute;
public DelegateCommand(Action executeMethod)
: this(executeMethod, () => true) {}
public DelegateCommand(Action executeMethod, Func<bool> _canExecute): base()
{
if (executeMethod == null || _canExecute == null) {
throw new ArgumentNullException(nameof(executeMethod),
Resources.DelegateCommandDelegatesCannotBeNull);
}
_executeMethod = executeMethod;
_canExecute = _canExecute;
}
public void Execute() => _executeMethod();
public bool CanExecute() => _canExecute();
protected override void Execute(object parameter) => Execute();
protected override bool CanExecute(object parameter) => CanExecute();
public DelegateCommand ObservesProperty<T>(Expression<Func<T>> propertyExpression)
{
ObservesPropertyInternal(propertyExpression);
return this;
}
public DelegateCommand ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
{
_canExecute = canExecuteExpression.Compile();
ObservesPropertyInternal(canExecuteExpression);
return this;
}
}
这里,DelegateCommandBase
实际上来自Prism.Commands
命名空间。
如果您不将Prism用作WPF的MVVM框架,则可以创建自己的DelegateCommandBase
副本(查找解决方案here)。
DelegateCommand
的成员,并在构造函数中对其进行初始化:public class MyViewModel
{
private DelegateCommand _okCommand;
public DelegateCommand OkCommand
{
get => _okCommand;
set => SetProperty(ref _okCommand, value);
}
public MyViewModel()
{
OkCommand = new PrismCommands.DelegateCommand(OkCommandHandler,
OkCanExecuteCommandHandler);
}
private void OkCommandHandler()
{
// ...
}
// This is important part: need to return true/false based
// on the need to enable or disable item
private bool OkCanExecuteCommandHandler() =>
return some_condition_to_enable_disable_item;
}
注意:确保每次发生可能影响some_condition_to_enable_disable_item
条件行为的更改时,都会引发执行更改事件。
例如,对于Prism,一旦发生与条件相关的更改(在我们的情况下为OkCommand.RaiseCanExecuteChanged();
),您可以调用RaiseCanExecuteChanged
方法。
小提示:对于Telerik WPF控件,您需要调用InvalidateCanExecute()
而不是RaiseCanExecuteChanged()
。
最后,我们的XAML
将如下所示:
<Button x:Name="btnOk"
Content="Ok"
Command="{Binding OkCommand}"/>
答案 3 :(得分:0)
上次我使用了来自Microsoft.Practices.Prism.Commands
的{{1}}个姓名。类Microsoft.Practices.Prism.dll
拥有自己的DelegateCommand
方法。所以,好处是你不必编写自己的RaiseCanExecuteChanged()
实现。
XAML:
ICommand
视图模型:
<StackPanel>
<CheckBox IsChecked="{Binding IsCanDoExportChecked}" />
<Button Command="{Binding ExportCommand}" Content="Export" />
</StackPanel>