为了学习 WPF Command
和 CommandParameter
,我有一个小型 WPF 应用程序,其中包含一个 TextBox
和一个 Button
。每当按下按钮时,都应调用 ICommandTest
,并将文本框的文本作为参数。
这很好用。下一步是:如果文本变得太小,则应禁用该按钮。
我使用MVVMLight来实现该命令。下面的代码足以在按下按钮时调用方法 Test。
到目前为止的代码
以下工作原理:启动时,文本框获得正确的初始文本。该按钮询问 View 模型此文本是否可以用作测试参数:
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
中的可编辑文本框和按钮。
<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 个字符,该按钮不会禁用。。每次按钮绑定(bind)的CommandParameter
值发生变化时,按钮都应该询问其命令是否可以执行。
如何做到这一点?
NotifyOnSourceUpdated
Yosef Bernal 建议添加 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,该按钮仍保持启用状态。
如果不能执行,我应该告诉按钮做什么吗?或者禁用该按钮是默认行为吗?
最佳答案
您可以将 TextBox
的 Text
属性绑定(bind)到 MyViewModel
上的 Text
属性。
<TextBox Name="ProposedTestValue" Text="{Binding Text}" Width="500" Height="20"/>
在 MyViewModel
中使用支持字段 _text
创建相应的 Text
属性。
private string _text;
public string Text
{
get => _text;
set
{
if (_text != value)
{
_text = value;
CommandTest.RaiseCanExecuteChanged();
}
}
}
只要更新 Text
属性,RaiseCanExecuteChanged
方法就会强制重新评估 CanExecute
,这取决于您的 UpdateSourceTrigger
。您不再需要 CommandParameter
,因为您可以在 View 模型中使用 Text
属性。
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.
}
注意:如果您打算更新 View 模型中的 Text
属性,则必须实现 INotifyPropertyChanged
,否则更改后的值将不会反射(reflect)在 View 中。
关于c# - WPF:如果 TextBox 中的文本发生更改,则更新按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63174956/