Silverlight 4, состояние ошибки проверки не отражается в моем собственном пользовательском элементе управления - PullRequest
1 голос
/ 08 сентября 2011

Состояние ошибки проверки не отражается в моем 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; }
}

1 Ответ

0 голосов
/ 14 октября 2011
new PropertyMetadata(null) -> new PropertyMetadata(null, **ValuePropertyChangedCallback**)
...