2008-10-09 61 views

回答

1

还没有做过这个,但个人,但一些良好的起点here。我想这些将成为未来版本的一部分,但现在我们可能不得不使用ASP.NET验证器作为起点。

4

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

要同时管理这些类型的错误的需要采取3个步骤:

  1. 识别错误处理程序或者在可视性层次结构中的控制或更高(例如,一个容器;在这种情况下,网格包含文本框)
  2. 将NotifyOnValidationError和ValidateOnException设置为true。后者告诉绑定引擎在发生异常时创建验证错误事件。前者告诉绑定引擎在发生验证错误时引发BindingValidationError事件。
  3. 创建在步骤1中

here采取命名事件处理程序。

示例代码:

// 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 
} 
+0

我期待看其控制由于在ValidationErrorEventArgs除外(http://msdn.microsoft .COM/EN-US /库/ system.windows.controls.validationerroreventargs.aspx)。所以我将BindingValidationError事件从网格移开,并移动到可能导致异常的文本框中。通过这种方式,我可以检查发件人参数中的例外引起的哪个控件。 – russau 2009-07-01 04:16:36

-1

你可能想看看PostSharp,它使归于您的客户端数据模型非常简单。

+0

如果您提供了如何使用PostSharp来帮助验证的示例,那么我将删除downvote。 – 2010-01-04 16:23:43

1

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

+0

正确的链接:http://jesseliberty.com/2008/10/22/it-aint-you-babe%E2%80%A6-a-not-a-bug-bug-in-datagrid/ – 2010-05-07 20:25:37

0

一个非常简单的验证控制源代码在此位置下式给出:

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

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

我不得不修改代码以包括如下childwindow在validatorbase类的条件:

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; 
     } 

    } 
}