Состояние ошибки проверки не отражается в моем UserControl. Я следил за подобным StackOverflow вопросом , чтобы решить его. Я не использую подход MVVM по выбору. Он использует службы WCF RIA с Entity Framework.
Но, похоже, это мне не помогло, что я упускаю или почему мой сценарий отличается?
Примечание. Если я добавлю TextBox (а не в UserControl) на своей главной странице, появится ошибка проверки.
Это мой код UserControl:
<UserControl x:Class="TestApp.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="25" d:DesignWidth="120">
<Grid x:Name="LayoutRoot" Background="White">
<TextBox x:Name="TextBox" />
</Grid>
</UserControl>
и это код , стоящий за UserControl:
public partial class MyUserControl : UserControl, INotifyDataErrorInfo
{
public MyUserControl()
{
InitializeComponent();
this.TextBox.BindingValidationError += MyUserControl_BindingValidationError;
Loaded += MyUserControl_Loaded;
this.TextBox.Unloaded += MyUserControl_Unloaded;
}
private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
{
this.TextBox.SetBinding(TextBox.TextProperty,
new Binding()
{
Source = this,
Path = new PropertyPath("Value"),
Mode = BindingMode.TwoWay,
NotifyOnValidationError = false,
ValidatesOnExceptions = true,
ValidatesOnDataErrors = true,
ValidatesOnNotifyDataErrors = true
});
}
private void MyUserControl_Unloaded(object sender, RoutedEventArgs e)
{
this.TextBox.ClearValue(TextBox.TextProperty);
}
public static DependencyProperty ValueProperty =
DependencyProperty.Register("Value",
typeof(string), typeof(MyUserControl),
new PropertyMetadata(null));
public static void ValuePropertyChangedCallback(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
((MyUserControl)dependencyObject).NotifyErrorsChanged("Value");
}
public string Value
{
get { return ((string)base.GetValue(ValueProperty)).Trim(); }
set { base.SetValue(ValueProperty, string.IsNullOrEmpty(value) ? " " : value.Trim()); }
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public IEnumerable GetErrors(string propertyName)
{
IEnumerable returnValue = null;
var errorMessage = "";
if (propertyName == "Value")
{
if (Validation.GetErrors(this).Count == 0)
{
errorMessage = "";
}
else
{
errorMessage = Validation.GetErrors(this).First().ErrorContent.ToString();
}
if (String.IsNullOrEmpty(errorMessage))
{
returnValue = null;
}
else
{
returnValue = new List<String> { errorMessage };
}
}
return returnValue;
}
public bool HasErrors
{
get { return Validation.GetErrors(this).Any(); }
}
private void MyUserControl_BindingValidationError(object sender, System.Windows.Controls.ValidationErrorEventArgs e)
{
this.NotifyErrorsChanged("Value");
}
public void NotifyErrorsChanged(string propertyName)
{
if (ErrorsChanged != null)
{
ErrorsChanged(this, new System.ComponentModel.DataErrorsChangedEventArgs(propertyName));
}
}
}
Я использую это так на моей главной странице:
<my:MyUserControl x:Name="UC"
Value="{Binding Path=Days, Mode=TwoWay,
NotifyOnValidationError=True,
ValidatesOnNotifyDataErrors=True}" />
Я также использую атрибуты проверки в System.ComponentModel.DataAnnotations, вот как это выглядит в RIAService.metadata.cs class:
internal sealed class tblRiskRegisterMetadata
{
//Metadata classes are not meant to be instantiated.
private tblRiskRegisterMetadata()
{ }
[Range(0, 1000, ErrorMessage = "Days should be 0-100")]
public int Days{ get; set; }
}