Как вы обрабатываете проверку в Silverlight? - PullRequest
4 голосов
/ 09 октября 2008

Как вы решили справиться с проверкой данных / контроля в своих приложениях Silverlight?

Ответы [ 6 ]

4 голосов
/ 13 октября 2008

Вы можете генерировать и фиксировать исключения проверки данных.

Для управления обоими этими типами ошибок необходимо выполнить 3 шага:

  1. Определите обработчик ошибок в элементе управления или выше в иерархии видимости (например, контейнер; в данном случае сетка, содержащая текстовое поле)
  2. Установите для NotifyOnValidationError и ValidateOnException значение true. Последний говорит Binding Engine создать событие ошибки проверки при возникновении исключения. Первый из них сообщает Binding Engine о возникновении события BindingValidationError при возникновении ошибки проверки.
  3. Создайте обработчик событий, названный в шаге 1.

Взято из здесь .

Пример кода:

// page.xaml.cs

private bool clean = true;


private void LayoutRoot_BindingValidationError( 
   object sender, ValidationErrorEventArgs e )
{
   if ( e.Action == ValidationErrorEventAction.Added )
   {
      QuantityOnHand.Background = new SolidColorBrush( Colors.Red );
      clean = false;
   }
   else if ( e.Action == ValidationErrorEventAction.Removed )
   {
      QuantityOnHand.Background = new SolidColorBrush( Colors.White );
      clean = true;
   }
}



// page.xaml

<Grid x:Name="LayoutRoot" Background="White" BindingValidationError="LayoutRoot_BindingValidationError" >

<TextBox x:Name="QuantityOnHand"   
    Text="{Binding Mode=TwoWay, Path=QuantityOnHand, 
        NotifyOnValidationError=true,  ValidatesOnExceptions=true }"
    VerticalAlignment="Bottom"
    HorizontalAlignment="Left"
    Height="30" Width="90"red
    Grid.Row="4" Grid.Column="1" />


// book.cs

public int QuantityOnHand
{
   get { return quantityOnHand; }
   set
   {
      if ( value < 0 )
      {
         throw new Exception( "Quantity on hand cannot be negative!" );
      }
      quantityOnHand = value;
      NotifyPropertyChanged( "QuantityOnHand" );
   }       // end set
}
1 голос
/ 19 ноября 2008

Если у вас возникают проблемы при попытке реализовать это, это не потому, что ваш код нарушен, а потому, что эта функция нарушена в DataGrid. Прочитайте статью Джесси Либерти здесь .

1 голос
/ 09 октября 2008

Лично я еще не много сделал, но есть хорошие отправные точки здесь . Я полагаю, что они появятся как часть будущего выпуска, но сейчас нам, вероятно, придется проверять свои собственные, используя валидаторы ASP.NET в качестве отправной точки.

0 голосов
/ 10 июня 2011
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Silverlight.Validators.Controls;

namespace Silverlight.Validators
{
    public enum ValidationType
    {
        Validator,
        OnDemand
    }


    public abstract class ValidatorBase : DependencyObject
    {
        protected ValidatorManager Manager { get; set; }


        public string ManagerName { get; set; }
        public ValidationType ValidationType { get; set; }
        public IIndicator Indicator { get; set; }
        public FrameworkElement ElementToValidate { get; set; }
        public bool IsRequired { get; set; }
        public bool IsValid { get; set; }
        public Brush InvalidBackground { get; set; }
        public Brush InvalidBorder { get; set; }
        public Thickness InvalidBorderThickness { get; set; }
        public string ErrorMessage { get; set; }

        private Brush OrigBackground = null;
        private Brush OrigBorder = null;
        private Thickness OrigBorderThickness = new Thickness(1);
        private object OrigTooltip = null;

        public ValidatorBase()
        {
            IsRequired = false;
            IsValid = true;
            ManagerName = "";
            this.ValidationType = ValidationType.Validator;
        }

        public void Initialize(FrameworkElement element)
        {
            ElementToValidate = element;
            element.Loaded += new RoutedEventHandler(element_Loaded);
        }

        private bool loaded = false;
        public UserControl UserControl { get; set; }
        public ChildWindow ChildUserControl { get; set; }
        private void element_Loaded(object sender, RoutedEventArgs e)
        {
            if (!loaded)
            {

                this.UserControl = FindUserControl(ElementToValidate);
                //UserControl o = FindUserControl(ElementToValidate);
                this.ChildUserControl = FindChildUserControl(ElementToValidate);
                //MessageBox.Show(o.GetType().BaseType.ToString());
                //no usercontrol.  throw error?
                if ((this.UserControl == null) && (this.ChildUserControl==null)) return;

                if (this.UserControl != null)
                    this.Manager = FindManager(this.UserControl, ManagerName);
                else if (this.ChildUserControl != null)
                    this.Manager = FindManager(this.ChildUserControl, ManagerName);


                if (this.Manager == null)
                {
                    System.Diagnostics.Debug.WriteLine(String.Format("No ValidatorManager found named '{0}'", ManagerName));
                    throw new Exception(String.Format("No ValidatorManager found named '{0}'", ManagerName));
                }

                this.Manager.Register(ElementToValidate, this);

                if (ValidationType == ValidationType.Validator)
                {
                    ActivateValidationRoutine();
                }

                //Use the properties from the manager if they are not set at the control level
                if (this.InvalidBackground == null)
                {
                    this.InvalidBackground = this.Manager.InvalidBackground;
                }

                if (this.InvalidBorder == null)
                {
                    this.InvalidBorder = this.Manager.InvalidBorder;

                    if (InvalidBorderThickness.Bottom == 0)
                    {
                        this.InvalidBorderThickness = this.Manager.InvalidBorderThickness;
                    }
                }

                if (this.Indicator ==null)
                {
                    Type x = this.Manager.Indicator.GetType();
                    this.Indicator = x.GetConstructor(System.Type.EmptyTypes).Invoke(null) as IIndicator;
                    foreach (var param in x.GetProperties())
                    {
                        var val = param.GetValue(this.Manager.Indicator, null);
                        if (param.CanWrite && val!= null && val.GetType().IsPrimitive)
                        {
                            param.SetValue(this.Indicator, val, null);
                        }
                    }
                }
                loaded = true;
            }
            ElementToValidate.Loaded -= new RoutedEventHandler(element_Loaded);
        }

        public void SetManagerAndControl(ValidatorManager manager, FrameworkElement element)
        {
            this.Manager = manager;
            this.ElementToValidate = element;
        }

        public bool Validate(bool checkControl)
        {
            bool newIsValid;
            if (checkControl)
            {
                newIsValid= ValidateControl() && ValidateRequired();
            }
            else
            {
                newIsValid = ValidateRequired();
            }

            if (newIsValid && !IsValid)
            {
                ControlValid();
            }
            if (!newIsValid && IsValid)
            {
                ControlNotValid();
            }
            IsValid=newIsValid;
            return IsValid;
        }

        public virtual void ActivateValidationRoutine()
        {
            ElementToValidate.LostFocus += new RoutedEventHandler(ElementToValidate_LostFocus);
            ElementToValidate.KeyUp += new KeyEventHandler(ElementToValidate_KeyUp);
        }

        /// <summary>
        /// Find the nearest UserControl up the control tree for the FrameworkElement passed in
        /// </summary>
        /// <param name="element">Control to validate</param>
        protected static UserControl FindUserControl(FrameworkElement element)
        {
            if (element == null)
            {
                return null;
            }
            if (element.Parent != null)
            {
                //MessageBox.Show(element.Parent.GetType().BaseType.ToString());
                if (element.Parent is UserControl)
                {
                    return element.Parent as UserControl;
                }
                return FindUserControl(element.Parent as FrameworkElement);
            }
            return null;
        }
        protected static ChildWindow FindChildUserControl(FrameworkElement element)
        {
            if (element == null)
            {
                return null;
            }
            if (element.Parent != null)
            {
                //MessageBox.Show(element.Parent.GetType().BaseType.ToString());
                if (element.Parent is ChildWindow)
                {
                    return element.Parent as ChildWindow;
                }
                return FindChildUserControl(element.Parent as FrameworkElement);
            }
            return null;
        }

        protected virtual void ElementToValidate_KeyUp(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(delegate() { Validate(false); });
        }

        protected virtual void ElementToValidate_LostFocus(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(delegate() { Validate(true); });
        }

        protected abstract bool ValidateControl();

        protected bool ValidateRequired()
        {
            if (IsRequired && ElementToValidate is TextBox)
            {
                TextBox box = ElementToValidate as TextBox;
                return !String.IsNullOrEmpty(box.Text);
            }
            return true;
        }

        protected void ControlNotValid()
        {
            GoToInvalidStyle();
        }

        protected void ControlValid()
        {
            GoToValidStyle();
        }

        protected virtual void GoToInvalidStyle()
        {
            if (!string.IsNullOrEmpty(this.ErrorMessage))
            {
                object tooltip = ToolTipService.GetToolTip(ElementToValidate);

                if (tooltip != null)
                {
                    OrigTooltip = tooltip;
                }

                //causing a onownermouseleave error currently...
                this.ElementToValidate.ClearValue(ToolTipService.ToolTipProperty);

                SetToolTip(this.ElementToValidate, this.ErrorMessage);
            }

            if (Indicator != null)
            {
                Indicator.ShowIndicator(this);
            }

            if (ElementToValidate is TextBox)
            {
                TextBox box = ElementToValidate as TextBox;

                if (InvalidBackground != null)
                {
                    if (OrigBackground == null)
                    {
                    OrigBackground = box.Background;
                    }
                    box.Background = InvalidBackground;
                }

                if (InvalidBorder != null)
                {
                    if (OrigBorder == null)
                    {
                    OrigBorder = box.BorderBrush;
                        OrigBorderThickness = box.BorderThickness;
                    }
                    box.BorderBrush = InvalidBorder;

                    if (InvalidBorderThickness != null)
                    {
                        box.BorderThickness = InvalidBorderThickness;
                    }
                }
            }   
        }

        protected virtual void GoToValidStyle()
        {
            if (!string.IsNullOrEmpty(this.ErrorMessage))
            {
                this.ElementToValidate.ClearValue(ToolTipService.ToolTipProperty);

                if (this.OrigTooltip != null)
                {
                    SetToolTip(this.ElementToValidate, this.OrigTooltip);
                }
            }

            if (Indicator != null)
            {
                Indicator.HideIndicator();
            }

            if (ElementToValidate is TextBox)
            {
                TextBox box = ElementToValidate as TextBox;
                if (OrigBackground != null)
                {
                    box.Background = OrigBackground;
                }

                if (OrigBorder != null)
                {
                    box.BorderBrush = OrigBorder;

                    if (OrigBorderThickness != null)
                    {
                        box.BorderThickness = OrigBorderThickness;
                    }
                }
            }
        }

        protected void SetToolTip(FrameworkElement element, object tooltip)
        {
            Dispatcher.BeginInvoke(() =>
                        ToolTipService.SetToolTip(element, tooltip));
        }

        private ValidatorManager FindManager(UserControl c, string groupName)
        {
            string defaultName = "_DefaultValidatorManager";
            var mgr = this.UserControl.FindName(ManagerName);
            if (mgr == null)
            {
                mgr = this.UserControl.FindName(defaultName);
            }
            if (mgr == null)
            {
                mgr = new ValidatorManager()
                {
                    Name = defaultName
                };
                Panel g = c.FindName("LayoutRoot") as Panel;
                g.Children.Add(mgr as ValidatorManager);
            }
            return mgr as ValidatorManager;
        }

        private ValidatorManager FindManager(ChildWindow c, string groupName)
        {
            string defaultName = "_DefaultValidatorManager";
            var mgr = this.ChildUserControl.FindName(ManagerName);
            if (mgr == null)
            {
                mgr = this.ChildUserControl.FindName(defaultName);
            }
            if (mgr == null)
            {
                mgr = new ValidatorManager()
                {
                    Name = defaultName
                };
                Panel g = c.FindName("LayoutRoot") as Panel;
                g.Children.Add(mgr as ValidatorManager);
            }
            return mgr as ValidatorManager;
        }

    }
}
0 голосов
/ 10 июня 2011

Очень простой исходный код управления проверкой приведен в этом месте:

http://silverlightvalidator.codeplex.com/SourceControl/changeset/view/20754#

Ниже приведены условия, при которых он работает. 1. Индикатор, отображающий недопустимые значения, предполагает положение элемента управления для проверки, поэтому элементы управления должны быть плотно упакованы в строку и столбец, чтобы указывать на смежность с элементом управления. 2. Это не работает для проверки в ChildWindow.

Мне пришлось изменить код, чтобы включить условия childwindow в класс validatorbase следующим образом:

0 голосов
/ 20 октября 2008

Возможно, вы захотите взглянуть на PostSharp , это упрощает атрибуцию вашей модели данных на стороне клиента.

...