我想做的是:当文本框中包含值“ 123”时,它应该启用该按钮并允许我单击它。
我找不到基于我的Button参数来触发Button命令(名为SpecialCommand.cs的类)的方法。您能支持我在哪里弄错了此MVVM模式吗?
WPF视图[MainWindow.xaml]:
<Window.Resources>
<ViewModel:MainWindowVM x:Key="WindowVm"></ViewModel:MainWindowVM>
</Window.Resources>
<Grid>
<StackPanel>
<TextBox x:Name="textBox" Margin="0, 5" Text="123"/>
<Button Content="Click me!" Margin="0, 5" Command="{Binding SpecialCommand, Source={StaticResource WindowVm}}" CommandParameter="{Binding Text, ElementName=textBox, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</StackPanel>
</Grid>
ViewModel [MainWindowVM.cs]:
public class MainWindowVM
{
private SpecialCommand _specialCommand;
public SpecialCommand SpecialCommand { get => _specialCommand; set => _specialCommand = value; }
public MainWindowVM()
{
_specialCommand = new SpecialCommand();
}
}
命令[SpecialCommand.cs]
public class SpecialCommand : ICommand
{
public bool CanExecute(object parameter)
{
if (parameter != null && (parameter as string) == "123")
return true;
return false;
}
public void Execute(object parameter)
{
MessageBox.Show("Button Pressed!");
}
public event EventHandler CanExecuteChanged;
}
我相信,也许这就是我要弄错的是,因为Button和Textbox位于视图中,所以我不需要在SpecialCommand实现中添加/修改任何方法。他们应该能够看到何时更改了属性。 像下面的CanExecuteChanged()一样,此命令会花费很多时间,并且似乎对这个小任务来说是多余的。
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
答案 0 :(得分:1)
您需要一种方法来告诉命令它应该检查它是否single('name')
。这是通过触发事件CanExecute
来完成的。它告诉按钮重新查询CanExecuteChanged
属性。
为此,我将一个text属性添加到您的视图模型并将文本框绑定到它。
在CanExecute
中添加方法:
SpecialCommand
在类public void TriggerCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
中添加属性:
MainWindowVM
查看用于实施private string _text;
public string Text
{
get { return _text; }
set {
if (value != _text) {
_text = value;
_specialCommand.TriggerCanExecuteChanged();
}
}
}
的模型(请参见评论):
INotifyPropertyChanged
答案 1 :(得分:0)
没有必要使它变得比需要的复杂。
public class MainWindowVM
{
private string m_OneTwoThree;
public string OneTwoThree{
get { return OneTwoThree; }
set {
if (m_OneTwoThree != value){
m_OneTwoThree = value;
NotifyPropertyChanged(nameof(OneTwoThree)); //if you need this let me know
}
}
}
public MainWindowVM()
{
}
public ICommand RandomCommand { get { return new RelayCommand(OnRandom, IsOneTwoThree); } }
private void OnRandom()
{
//do stuff
}
private bool IsOneTwoThree(){
if (OneTwoThree == "123"){
return true;
}
return false;
}
}
您还必须更新您的xaml
,我认为它无法找到“ OneTwoThree”,因此您必须自己绑定它,但通常会这样做。
<StackPanel>
<TextBox x:Name="textBox" Margin="0, 5" Text="{Binding OneTwoThree}"/>
<Button Content="Click me!" Margin="0, 5" Command="{Binding RandomCommand, Source={StaticResource WindowVm}}"/>
</StackPanel>
如果您有任何问题,请问。
这是我的RelayCommand:使用RelayCommand(“执行的东西”,“如果函数返回true,则可以执行”);
public class RelayCommand : ICommand
{
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
private Action methodToExecute;
private Func<bool> canExecuteEvaluator;
public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
{
this.methodToExecute = methodToExecute;
this.canExecuteEvaluator = canExecuteEvaluator;
}
public RelayCommand(Action methodToExecute)
: this(methodToExecute, null)
{
}
public bool CanExecute(object parameter)
{
if (this.canExecuteEvaluator == null) {
return true;
}
else {
bool result = this.canExecuteEvaluator.Invoke();
return result;
}
}
public void Execute(object parameter)
{
this.methodToExecute.Invoke();
}
}