WPF MVVM-带文本框的简单绑定按钮(Icommand)

时间:2018-09-28 15:03:11

标签: c# wpf mvvm binding icommand

我想做的是:当文本框中包含值“ 123”时,它应该启用该按钮并允许我单击它。

Solution ImageView Image

我找不到基于我的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; }
    }

2 个答案:

答案 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();
    }
}
相关问题