我有一个带有多个控件的WPF表单,并且我希望在且仅当那些控件上的各种条件为真时才启用按钮(“分配”)。一些条件包括测试文本框是否为空。
我最初是通过将文本框的内容绑定到属性并IsEnabled
在XAML中绑定按钮的属性来实现的:
<TextBox Name="NewName" Text="{Binding NewName}" />
(etc)
<Button Name="Assign" ... IsEnabled="{Binding Path=AssignEnabled}" />
在C#ViewModel中使用相应的方法:
public bool AssignEnabled
{
get
{
return !string.IsNullOrWhiteSpace(this.NewName) && ... (etc)
}
set
{
...
this.NotifyPropertyChanged("AssignEnabled");
...
}
}
问题是,这导致按钮在相应文本框中失去焦点时更新,而不是在更改文本时更新。我本可以使用TextChanged
XAML中每个文本框的属性来调用代码,但这似乎过于复杂了。
为了解决这个问题,我删除了绑定,并切换到DataTriggers,如下所示:
<Button Name="Assign" ... >
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsChecked, ElementName=NewNameOption}" Value="true" />
<Condition Binding="{Binding Text, ElementName=NewName}" Value="{x:Static sys:String.Empty}" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
...
(more conditions here)
...
</Style.Triggers>
</Style>
</Button.Style>
</Button>
这绝对好用。唯一的缺点是我以前编写的用于测试IsEnabled
按钮状态的单元测试不再可用(因为它们使用AssignEnabled
的ViewModel属性不再绑定到按钮)。
为了使这些单元测试能够正常工作,我需要该AssignEnabled
属性来反映IsEnabled
按钮的状态。我希望能够通过添加OneWayToSource
绑定来解决此问题,如下所示:
<Button Name="Assign" ... IsEnabled="{Binding AssignEnabled, Mode=OneWayToSource}">
将属性更改为:
public bool AssignEnabled { get; set; }
但是,即使将绑定设置为OneWayToSource
,该绑定似乎仍会覆盖DataTriggers,因为启用/禁用按钮根本不再起作用。
我知道还有其他选择,例如使用Converter或Implementing ICommand
,但我希望尽可能保持简单并修复上述方法(或至少了解为什么它不起作用)。如何IsEnabled
在不违反ViewModel范例或防止DataTriggers正常工作的情况下访问按钮的属性?
您可以保留第一个解决方案并设置UpdateSourceTrigger=PropertyChanged
绑定。这样,绑定将在文本更改时立即更改,而不仅是在失去焦点时。顺便说一下,此解决方案为您提供了更灵活的选择,因为您可以在自己的字段上执行更复杂的测试(例如,测试电子邮件地址格式)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句