如何在WPF中将INotifyDataErrorInfo的错误传递至嵌套用户控件内部的TextBox?
如何在WPF中将INotifyDataErrorInfo的错误传递至嵌套用户控件内部的TextBox?
针对你遇到的INotifyDataErrorInfo验证错误边框范围不对的问题,我给你整理了一套可行的解决方案,能精准把错误提示定位到最内层的TextBox上,同时保留用户控件的封装性:
问题分析
现在验证错误会从MainViewModel传递到FormGroupUserControl,导致整个控件被红色边框包裹。我们需要把错误传递链延伸到PlaceholderTextBoxUserControl,最终让内部的TextBox显示错误边框,外层控件不再显示多余的错误装饰。
具体解决步骤
1. 阻止FormGroupUserControl显示错误边框
首先,在FormGroupUserControl的根UserControl标签里,把默认的错误模板设为空,这样整个FormGroup就不会再被红色边框包裹:
<UserControl x:Class="YourNamespace.FormGroupUserControl" ... Validation.ErrorTemplate="{x:Null}">
2. 把验证错误传递到PlaceholderTextBoxUserControl
在FormGroupUserControl中,修改PlaceholderTextBox的绑定配置,完成错误传递的衔接:
- 给绑定添加
ValidatesOnNotifyDataErrors=True,确保WPF能识别INotifyDataErrorInfo返回的错误 - 用
Validation.ValidationAdornerSiteFor把FormGroup的验证错误传递给内层的PlaceholderTextBox
<Label /> <PlaceholderTextBoxUserControl Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}" Validation.ValidationAdornerSiteFor="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>
3. 让PlaceholderTextBox内部的TextBox显示错误边框
同样先阻止PlaceholderTextBox本身显示错误边框,再通过Style触发器让内部TextBox在有错误时自动显示红色边框:
第一步:给PlaceholderTextBox设置空错误模板
<UserControl x:Class="YourNamespace.PlaceholderTextBoxUserControl" ... Validation.ErrorTemplate="{x:Null}">
第二步:给内部TextBox添加Style触发器
当外层PlaceholderTextBox存在验证错误(HasError=True)时,自动给TextBox设置红色边框:
<TextBlock /> <TextBox Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}, ValidatesOnNotifyDataErrors=True}"> <TextBox.Style> <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}"> <Style.Triggers> <DataTrigger Binding="{Binding HasError, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="True"> <Setter Property="BorderBrush" Value="Red"/> <Setter Property="BorderThickness" Value="1"/> <!-- 可选:如果需要保留WPF默认的错误提示(比如右上角感叹号),可以添加下面的模板 --> <!-- <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <DockPanel> <AdornedElementPlaceholder/> <TextBlock Foreground="Red" Text="!" Margin="2,0,0,0" FontSize="12"/> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> --> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox>
关键注意点
- 所有涉及的绑定都要加上
ValidatesOnNotifyDataErrors=True,这是WPF识别INotifyDataErrorInfo错误的必要配置 - 这套方案完全基于XAML和WPF原生验证机制,不需要额外的代码-behind逻辑,同时保留了用户控件的复用性
备注:内容来源于stack exchange,提问作者mauriziopatino
相关产品推荐
相关产品推荐

