WPF:如果 TextBox 中的文本更改,则更新按钮 [英] WPF: Update button if text in TextBox changes

查看:49
本文介绍了WPF:如果 TextBox 中的文本更改,则更新按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了学习 WPF CommandCommandParameter 我有一个带有一个 TextBox 和一个 Button 的小型 WPF 应用程序.每当按钮被按下时,ICommandTest 应该以文本框的文本作为参数被调用.

To learn WPF Command and CommandParameter I have a small WPF application with one TextBox and one Button. Whenever the button is pressed, ICommandTest should be called with the text of the text box as parameter.

这很好用.下一步是:如果文本变得太小,则应禁用该按钮.

This works fine. The next step is: if the text becomes too small, the button should be disabled.

我使用 MVVMLight 来实现命令.下面的代码足以在按下按钮时调用方法 Test.

I use MVVMLight to implement the command. The code below is enough to call method Test whenever the button is pressed.

以下有效:在启动时,文本框获得其正确的初始文本.该按钮询问视图模型是否可以将此文本用作测试的参数:

The following works: At startup the text box gets its proper initial text. The button asks the view model whether this text can be used as parameter for the test:

public class MyViewModel
{
    public ICommand CommandTest {get;}

    public MyViewModel()
    {
        this.CommandTest = new RelayCommand<string>(this.Test, this.CanTest); 
    }

    private bool CanTest(string text)
    {
        // text should have a minimum length of 4
        return text != null && text.Length >= 4;
    }
    private void Test(string text)
    {
        //...
    }

    // ...

}

XAML:水平 StackPanel 中的可编辑文本框和按钮.

XAML: An editable text box and a button in a horizontal StackPanel.

<StackPanel Name="Test" Orientation="Horizontal" Background="AliceBlue">
    <TextBox Name="ProposedTestValue"
             Text="Alle eendjes zwemmen in het water"
             Width="500" Height="20"/>

    <Button x:Name="ButtonTest" Content="Change"
                    Height="auto" Width="74"
                    Padding="5,2"
                    Command="{Binding Path=CommandTest}"
                    CommandParameter="{Binding ElementName=ProposedTestValue, Path=Text}"/>
</StackPanel>

文本更改

如果我更改文本并按下按钮,则会使用更改后的文本调用命令.所以 CommandCommandParameter 起作用了.

但是,如果文本小于 4 个字符,按钮不会禁用..每次按钮绑定的CommandParameter的值发生变化时,按钮都要询问它的命令是否可以执行.

However, if the text becomes smaller than 4 characters, the button doesn't disable.. Every time that the value of the bound CommandParameter of the button changes, the button should ask its command if it can be executed.

如何做到这一点?

Yosef Bernal 建议添加 NotifyOnSourceUpdated:

Yosef Bernal suggested to add NotifyOnSourceUpdated:

<Button x:Name="ButtonChangeTestText" Content="Change"
                Height="30" Width="74" Padding="5,2"
                Command="{Binding Path=CommandTest}"
                CommandParameter="{Binding ElementName=ProposedTestTextValue,
                    Path=Text, NotifyOnSourceUpdated=True}"/>

唉,这并没有改变任何东西:在启动时调用了初始 CanTest,并使用了正确的参数.更改文本不会导致 CanTest.如果我按下按钮 CanTest 被调用正确的值.如果文本很小,CanTest 返回 false,因此不执行命令.但是,即使 CanExecute 返回 false,该按钮仍保持启用状态.

Alas, that didn't change anything: at startup an initial CanTest is called, with the correct parameter. Changing the text doesn't cause a CanTest. If I press the button CanTest is called with the correct value. If the text is small, CanTest returns false, and thus the command is not execute. However, even though CanExecute returned false, the button remains enabled.

如果不是 CanExecute,我应该告诉 Button 怎么办?或者禁用按钮是默认行为?

Should I tell the Button what to do if not CanExecute? Or is disabling the button the default behaviour?

推荐答案

您可以将 TextBoxText 属性绑定到 TextMyViewModel 上的属性.

You can bind the Text property of your TextBox to a Text property on MyViewModel.

<TextBox Name="ProposedTestValue" Text="{Binding Text}" Width="500" Height="20"/>

在带有支持字段 _textMyViewModel 中创建相应的 Text 属性.

Create a corresponding Text property in your MyViewModel with a backing field _text.

private string _text;

public string Text
{
   get => _text;
   set
   {
      if (_text != value)
      {
         _text = value;
         CommandTest.RaiseCanExecuteChanged();
      }
   }
}

RaiseCanExecuteChanged 方法将在 Text 属性更新时强制重新评估 CanExecute,这取决于您的 UpdateSourceTrigger.您不再需要 CommandParameter,因为您可以在视图模型中使用 Text 属性.

The RaiseCanExecuteChanged method will force a re-evaluation of CanExecute whenever the Text property is updated, which depends on your UpdateSourceTrigger. You do not need the CommandParameter anymore, since you can use the Text property in your view model.

public MyViewModel()
{
   this.CommandTest = new RelayCommand(this.Test, this.CanTest); 
}

private bool CanTest()
{
   return Text != null && Text.Length >= 4;
}

private void Test()
{
   // ...use "Text" here.
}

注意:如果你打算从你的视图模型更新Text属性,你必须实现INotifyPropertyChanged,否则改变的值会不会反映在视图中.

Note: If you intend to update the Text property from your view model, you have to implement INotifyPropertyChanged, otherwise the changed value will not be reflected in the view.

这篇关于WPF:如果 TextBox 中的文本更改,则更新按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆