问题描述
我采用了似乎是使用 IDataErrorInfo 接口和样式在 WPF 中验证文本框的标准方法,如下所示.但是,当页面无效时,如何禁用保存"按钮?这是通过触发器以某种方式完成的吗?
I've adopted what appears to be the standard way of validating textboxes in WPF using the IDataErrorInfo interface and styles as shown below. However, how can I disable the Save button when the page becomes invalid? Is this done somehow through triggers?
Default Public ReadOnly Property Item(ByVal propertyName As String) As String Implements IDataErrorInfo.Item
Get
Dim valid As Boolean = True
If propertyName = "IncidentCategory" Then
valid = True
If Len(IncidentCategory) = 0 Then
valid = False
End If
If Not valid Then
Return "Incident category is required"
End If
End If
Return Nothing
End Get
End Property
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="3" />
<Setter Property="Height" Value="23" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
推荐答案
两件事:
首先,我建议使用 RoutedCommand ApplicationCommands.Save
来实现对保存按钮的处理.
First, I would recommend using the RoutedCommand ApplicationCommands.Save
for implementing the handling of the save button.
如果您还没有查看 WPF 命令模型,您可以获取独家新闻 这里.
If you haven't checked out the WPF Command model, you can get the scoop here.
<Button Content="Save" Command="Save">
现在,要实现该功能,您可以将命令绑定添加到 Window/UserControl 或 Button 本身:
Now, to implement the functionality, you can add a command binding to the Window/UserControl or to the Button itself:
<Button.CommandBindings>
<CommandBinding Command="Save"
Executed="Save_Executed" CanExecute="Save_CanExecute"/>
</Button.CommandBindings>
</Button>
在后面的代码中实现这些:
Implement these in code behind:
private void Save_Executed(object sender, ExecutedRoutedEventArgs e)
{
}
private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
}
在Save_CanExecute
中,根据文本框上绑定的有效性设置e.CanExecute
.
In Save_CanExecute
, set e.CanExecute
based on the validity of the binding on the text box.
如果您想使用 MVVM(模型-视图-视图模型)设计模式来实现,请查看 Josh Smith 在 CommandSinkBinding.
If you want to implement using the MVVM (Model-View-ViewModel) design pattern, check out Josh Smith's post on CommandSinkBinding.
最后一点:如果您希望在 TextBox
中的值更改后立即更新启用/禁用,请设置 UpdateSourceTrigger="PropertyChanged"
TextBox
的绑定.
One final note: If you want the enable/disable to be updated as soon as the value in the TextBox
is changed, set UpdateSourceTrigger="PropertyChanged"
on the binding for the TextBox
.
如果您想根据控件中的所有绑定来验证/无效,这里有一些建议.
If you want to validate/invalidate based on all of the bindings in the control, here are a few suggestions.
1) 您已经在实现 IDataErrorInfo
.尝试实现 IDataErrorInfo.Error
属性,以便它返回对您绑定到的所有属性都无效的字符串.这仅在您的整个控件绑定到单个数据对象时才有效.设置 e.CanExecute = string.IsNullOrEmpty(data.Error);
1) You are already implementing IDataErrorInfo
. Try implementing the IDataErrorInfo.Error
property such that it returns the string that is invalid for all of the properties that you are binding to. This will only work if your whole control is binding to a single data object. Set e.CanExecute = string.IsNullOrEmpty(data.Error);
2) 使用反射来获取相关控件上的所有公共静态 DependencyProperties.然后在每个属性的循环中调用 BindingOperations.GetBindingExpression(relevantControl, DependencyProperty)
以便您可以测试验证.
2) Use reflection to get all of the public static DependencyProperties on the relevant controls. Then call BindingOperations.GetBindingExpression(relevantControl, DependencyProperty)
in a loop on each property so you can test the validation.
3) 在构造函数中,手动创建嵌套控件上所有绑定属性的集合.在 CanExecute 中,遍历此集合并通过使用 BindingOperation.GetBindingExpression()
获取表达式然后检查 来验证每个
.DependencyObject
/DepencyProperty
组合>BindingExpression.HasError
3) In the constructor, manually create a collection of all bound properties on nested controls. In CanExecute, iterate through this collection and validate each DependencyObject
/DepencyProperty
combination by using BindingOperation.GetBindingExpression()
to get expressions and then examining BindingExpression.HasError
.
这篇关于如果验证失败,则禁用 WPF 中的保存按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!