WPF:如果 TextBox 中的文本更改,则更新按钮 [英] WPF: Update button if text in TextBox changes
问题描述
为了学习 WPF Command
和 CommandParameter
我有一个带有一个 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>
文本更改
如果我更改文本并按下按钮,则会使用更改后的文本调用命令.所以 Command
和 CommandParameter
起作用了.
但是,如果文本小于 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?
推荐答案
您可以将 TextBox
的 Text
属性绑定到 Text
MyViewModel
上的属性.
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"/>
在带有支持字段 _text
的 MyViewModel
中创建相应的 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屋!