我有一个TextBox供用户输入字符串,并且"添加"按钮用值执行某些任务。我在DelegateCommand中添加了一个CanExecute方法,以便该按钮仅在框中有文本时才有效。
但是,它一直处于禁用状态 - 即使条件为真也是如此。在框中输入不会启用按钮。
<TextBox Text="{Binding BuildEntryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding AddBuildCommand}" Content="Add" />
this.AddBuildCommand = new DelegateCommand(() => this.AddBuild(), () => this.CanAddBuild());
private bool CanAddBuild()
{
if (this.BuildEntryText != null)
{
return true;
}
else
{
return false;
}
}
我之前已经发生了这种情况(并不总是使用相同类型的控件),通常我会删除CanExecute并将其更改为&#34; if&#34;检查动作方法。但是这一次,我实际上必须让它工作并将按钮变成灰色的&#34;正确的&#34;方式。
非常感谢任何见解。提前谢谢。
更新
我已将RaiseCanExecuteChanged添加到BuildEntryText属性的set部分。现在按钮开始禁用,并在首次输入文本时启用。但是,即使删除了文本或添加功能清除了该框,它仍会保持启用状态。
public string BuildEntryText
{
get
{
return this.buildEntryText;
}
set
{
this.SetProperty<string>(ref this.buildEntryText, value);
this.AddBuildCommand.RaiseCanExecuteChanged();
}
}
答案 0 :(得分:0)
您的委托命令需要重新查询以检查命令是否可以执行。委托命令定义在UI线程上引发的名为CanExecuteChanged
的事件,以使每个调用控件重新查询以检查命令是否可以执行< / p>
这就是Delegate Command的样子(你的也可能类似)
public class DelegateCommand<T> : System.Windows.Input.ICommand
{
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
public DelegateCommand(Action<T> execute)
: this(execute, null)
{
}
public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
return true;
return _canExecute((parameter == null) ? default(T) :(T)Convert.ChangeType(parameter, typeof(T)));
}
public void Execute(object parameter)
{
_execute((parameter == null) ? default(T) : (T)Convert.ChangeType(parameter, typeof(T)));
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
您将它绑定到TextBox
这是一个示例 的 ViewModel.cs 强>
public class ViewModel
{
private readonly DelegateCommand<string> MyButtonCommand;
public ViewModel()
{
MyButtonCommand= new DelegateCommand<string>(
(s) => { MessageBox.Show("Command Executed")}, //Execute
(s) => { return !string.IsNullOrEmpty(_input); } //CanExecute
);
}
public DelegateCommand<string> AddBuildCommand
{
get { return MyButtonCommand; }
}
private string _input;
public string BuildEntryText
{
get { return _input; }
set
{
_input = value;
MyButtonCommand.RaiseCanExecuteChanged();
}
}
}
并在 XAML
中 <TextBox Text="{Binding BuildEntryText, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding AddBuildCommand}" Content="Add" />
答案 1 :(得分:0)
我发现这是一个由两部分组成的问题,而且我的DelegateCommand实际上并不存在问题(至少,并非完全如此)。
1)我需要调用RaiseCanExecuteChanged,正如Rachel建议的那样,或者用户界面不会刷新控件的IsEnabled属性。
2)我需要添加一个附加条件来检查字符串的长度,而不是只检查它是否为空。显然,一个空的TextBox以null开头,但如果你添加字符然后删除它们,它就不会再次返回null。它是一个长度为0的字符串。 / p>
<TextBox Text="{Binding BuildEntryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding AddBuildCommand}" Content="Add" />
public DelegateCommand AddBuildCommand { get; private set; }
this.AddBuildCommand = new DelegateCommand(() => this.AddBuild(), () => this.CanAddBuild());
public string BuildEntryText
{
get
{
return this.buildEntryText;
}
set
{
this.SetProperty<string>(ref this.buildEntryText, value);
// PART 1:
this.AddBuildCommand.RaiseCanExecuteChanged();
}
}
private bool CanAddBuild()
{
// PART 2:
if (this.BuildEntryText != null && this.BuildEntryText.Length > 0)
{
return true;
}
else
{
return false;
}
}