设置 UserControl 的特定子项的错误模板
Posted
技术标签:
【中文标题】设置 UserControl 的特定子项的错误模板【英文标题】:Set error template of a specific child of a UserControl 【发布时间】:2022-01-13 00:42:08 【问题描述】:我正在尝试了解如何将错误模板添加到 UserControl
的子代,并且我看到了其他类似的问题,但我仍然无法解决这个问题。
我的目标是创建一个具有TextBox
和Label
的UserControl
,以及可选的只读TextBox
。我已经实现了很多功能并且一切正常,除了整个UserControl
会在验证错误的情况下出现红色边框。
我尝试将Validation.ValidationAdornerSite
添加到UserControl
的根元素,但没有成功。
另外,这个想法是验证应该在模型类中完成,所以我不想在UserControl
中放置任何验证机制。
在这种情况下,我真的不明白绑定系统是如何工作的。整个UserControl
在错误中突出显示是有道理的,因为它是绑定到Model
属性的UserControl
属性,但我希望能够将错误“重定向”到Validation.ValidationAdornerSite
的孩子。我错过了什么或误解了什么?例如,如何突出显示TextBox
“txt1”?
提前致谢!
这是我能想到的最小的例子:
MyControl.xaml
<UserControl x:Class="MyNamespace.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel x:Name="ctRoot">
<Label x:Name="lbTitle" Content="MyLabel"/>
<TextBox x:Name="txt1" Text="Binding Text"/>
<TextBox x:Name="txt2"/>
</StackPanel>
</UserControl>
MyControl.xaml.cs
public partial class MyControl : UserControl
public MyControl()
InitializeComponent();
ctRoot.DataContext = this;
public static readonly DependencyProperty TextProperty = DependencyProperty
.Register("Text", typeof(string), typeof(MyControl), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Text
get return (string)GetValue(TextProperty);
set SetValue(TextProperty, value);
Model.cs
public class Model : INotifyDataErrorInfo, INotifyPropertyChanged
private string m_prop;
public string MyProp
get => m_prop;
set
m_errors.Clear();
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(MyProp)));
if (value.Length == 0)
m_errors.Add("Cannot be empty");
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(MyProp)));
m_prop = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyProp)));
private List<string> m_errors = new List<string>();
public bool HasErrors => m_errors.Count > 0;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public event PropertyChangedEventHandler PropertyChanged;
public IEnumerable GetErrors(string propertyName)
return m_errors;
MyWindow.xaml
<Window x:Class="MyNamespace.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
Title="MyWindow" Width="200" Height="200">
<StackPanel>
<local:MyControl Text="Binding MyProp" Margin="10"/>
</StackPanel>
</Window>
MyWindow.xaml.cs
public partial class MyWindow : Window
public Model model = new Model();
public MyWindow()
InitializeComponent();
DataContext = model;
【问题讨论】:
【参考方案1】:您可以使用Validation.ValidationAdornerSiteFor
更改显示哪个元素以指示发生了错误。
<UserControl x:Class="WpfApp1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="myControl">
<StackPanel x:Name="ctRoot">
<Label x:Name="lbTitle" Content="MyLabel"/>
<TextBox x:Name="txt1" Text="Binding Text, ElementName=myControl"
Validation.ValidationAdornerSiteFor="Binding ElementName=myControl"/>
<TextBox x:Name="txt2"/>
</StackPanel>
</UserControl>
【讨论】:
解决了这个问题。但是你知道为什么在 UserControl 上使用Validation.ValidationAdornerSite
不起作用吗?因为文档的备注部分说“Validation.ValidationAdornerSite 和 Validation.ValidationAdornerSiteFor 附加属性相互引用,您可以设置任何一个。”。
@RodolfoRibeiro 因为这将无法解决后代的名称并导致绑定错误。以上是关于设置 UserControl 的特定子项的错误模板的主要内容,如果未能解决你的问题,请参考以下文章
不支持在 UserControl 上设置 Template 属性
属于 UserControl 子级的错误与 UserControl 而不是子级相关联