【发布时间】: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;
}
}
【问题讨论】:
标签: c# wpf xaml data-binding