您是如何决定在Silverlight应用程序中处理数据/控件验证的?如何在Silverlight中处理验证?
回答
还没有做过这个,但个人,但一些良好的起点here。我想这些将成为未来版本的一部分,但现在我们可能不得不使用ASP.NET验证器作为起点。
您可以抛出并捕获数据验证异常。
要同时管理这些类型的错误的需要采取3个步骤:
- 识别错误处理程序或者在可视性层次结构中的控制或更高(例如,一个容器;在这种情况下,网格包含文本框)
- 将NotifyOnValidationError和ValidateOnException设置为true。后者告诉绑定引擎在发生异常时创建验证错误事件。前者告诉绑定引擎在发生验证错误时引发BindingValidationError事件。
- 创建在步骤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
}
你可能想看看PostSharp,它使归于您的客户端数据模型非常简单。
如果您提供了如何使用PostSharp来帮助验证的示例,那么我将删除downvote。 – 2010-01-04 16:23:43
如果您在尝试实现此操作时遇到问题,这不是因为代码已损坏,这是因为DataGrid中的功能已损坏。查看Jesse Liberty here的文章。
正确的链接: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
一个非常简单的验证控制源代码在此位置下式给出:
http://silverlightvalidator.codeplex.com/SourceControl/changeset/view/20754#
以下是在其下它工作的条件。 1.显示无效值的指示器假定要验证控件的位置,因此控件应该紧密排列在行和列中,以便它指示与控件相邻。 2.它不适用于在ChildWindow上进行验证。
我不得不修改代码以包括如下childwindow在validatorbase类的条件:
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;
}
}
}
- 1. 如何处理Silverlight 4中的验证严重性?
- 2. Silverlight验证摘要不处理ValidationException
- 3. 在Silverlight中处理经过身份验证的会话超时
- 4. 验证在Silverlight中
- 5. 如何在SilverLight中处理会话
- 6. 如何处理文本框验证?
- 7. Grails:如何处理JSR 303 bean验证
- 8. 如何处理的学说2验证
- 9. 如何处理多个身份验证
- 10. 如何处理ASP.NET身份验证
- 11. 如何处理非法参数验证
- 12. 在ASP.NET Web API中处理ModelState验证
- 13. 在Okhttp中处理身份验证
- 14. 如何在liferay登录portlet中处理无效身份验证
- 15. 如何在ASP.NET中禁用JavaScript时处理验证
- 16. 如何在WebView中处理基本身份验证
- 17. 如何处理JSON在Laravel中返回验证器错误
- 18. 如何在MVC3中处理服务层验证
- 19. 如何在IE7和IE8中处理表单身份验证
- 20. 如何处理“需要验证”在硒中弹出
- 21. 如何在ASP.NET Entity Framework中处理Microsoft身份验证
- 22. 如何在ember.js应用程序中处理验证
- 23. 如何在Express(NodeJS)中验证和处理表单
- 24. 如何处理未在HTML5中验证的元素?
- 25. 如何在Django中进行表单验证/处理?
- 26. 如何在MVC Core中处理空模型验证?
- 27. 如何处理Silverlight 4和WPF应用程序的WCF身份验证
- 28. 如何在Silverlight中验证主机服务器的证书?
- 29. Silverlight的验证
- 30. 如何处理Silverlight中的DateTime和TimeZone?
我期待看其控制由于在ValidationErrorEventArgs除外(http://msdn.microsoft .COM/EN-US /库/ system.windows.controls.validationerroreventargs.aspx)。所以我将BindingValidationError事件从网格移开,并移动到可能导致异常的文本框中。通过这种方式,我可以检查发件人参数中的例外引起的哪个控件。 – russau 2009-07-01 04:16:36