4

您是如何决定在 Silverlight 应用程序中处理数据/控制验证的?

4

6 回答 6

4

您可以抛出和捕获数据验证异常。

要管理这两种类型的错误,需要采取 3 个步骤:

  1. 识别控件中的错误处理程序或可见性层次结构中更高的错误处理程序(例如,容器;在本例中为包含文本框的网格)
  2. 将 NotifyOnValidationError 和 ValidateOnException 设置为 true。后者告诉绑定引擎在发生异常时创建验证错误事件。前者告诉绑定引擎在发生验证错误时引发 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
}
于 2008-10-13T19:25:01.343 回答
1

如果您在尝试实现此功能时遇到问题,这不是因为您的代码已损坏,而是因为 DataGrid 中的功能已损坏。在这里查看 Jesse Liberty 的文章。

于 2008-11-19T00:21:05.550 回答
1

个人还没有做太多这件事,但这里有一些很好的起点。我想这些将作为未来版本的一部分出现,但现在我们可能不得不使用 ASP.NET 验证器作为起点推出我们自己的。

于 2008-10-09T18:10:42.133 回答
0

此位置提供了一个非常简单的验证控制源代码:

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

以下是它的工作条件。1. 显示无效值的指示器假定要验证的控件的位置,因此控件应紧密排列在行和列中,以便指示与控件相邻。2. 对 ChildWindow 的验证不起作用。

我不得不修改代码以在validatorbase类中包含childwindow的条件,如下所示:

于 2011-06-10T04:08:41.267 回答
0
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;
        }

    }
}
于 2011-06-10T04:16:54.350 回答
-1

您可能想查看PostSharp,它使您的客户端数据模型的归属变得非常简单。

于 2008-10-19T21:05:10.547 回答