关于Silverlight Input Data Validation <二>
2011-02-17 23:04 步丈天涯 阅读(575) 评论(3) 编辑 收藏 举报关于Silverlight Input Data Validation <一>里已经讲过如何用INotifyPropertyChanged接口来实现数据的Validation。
现在问题来了,用INotifyPropertyChanged接口来实现数据Validation,会有红色ToolTip绑定到目标控件上。
这是好事,但如果我们不想让验证信息绑定到目标控件上,而是让它显示到其他地方,如显示到TextBlock上,如何做呢?
关于INotifyDataErrorInfo接口的介绍,详见MSDN INotifyDataErrorInfo Interface。
要点:
1.ValidatesOnNotifyDataErrors在默认情况下是True的,所以,不想让验证失败的消息显示出来,请把它设置为False。
2.请指定你所要验证地控件的DataContext。
3.INotifyPropertyChanged接口里有个方法GetErrors(),实现它,并让他返回你想要的东西,比如返回error内容。
以下是我的代码:
(1)xaml部分:
//对应上面的要点1 <TextBox Text="{Binding Mode=TwoWay, Path=MyID, ValidatesOnNotifyDataErrors=False}" Height="25" Name="txtMyID" Width="100" /> <Button Content="Click" Height="25" HorizontalAlignment="Center" Name="btnClick" Click="btnClick_Click" VerticalAlignment="Top" Width="80" /> <TextBlock Height="25" HorizontalAlignment="Left" Name="tbErrorMsg" VerticalAlignment="Center" Width="140" />
(2)xaml.cs部分:
public partial class MainPage : UserControl { MyPageValidation mv; public MainPage() { InitializeComponent(); //对应上面的要点2 mv = new MyPageValidation(); txtMyID.DataContext = mv; } private void btnClick_Click(object sender, RoutedEventArgs e) { this.tbErrorMsg.Text = string.Empty; if(mv.HasErrors) { //对应上面的要点3 List<String> errors = (List<String>)mv.GetErrors("MyID"); if (errors != null) { this.tbErrorMsg.Text = errors[0]; this.tbErrorMsg.Foreground = new SolidColorBrush(Colors.Red); } } } }
(3)MyPageValidation验证类部分:
public class MyPageValidation : INotifyDataErrorInfo { private string _MyID; public string MyID { get { return _MyID; } set { if (IsIdValid(value) && _MyID != value) _MyID = value; } } public bool IsIdValid(string value) { bool isValid = true; int resultOut = 0; if (!Int32.TryParse(value,out resultOut)) { AddError("MyID", ID_ERROR); isValid = false; } else RemoveError("MyID", ID_ERROR); return isValid; } private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>(); private const string ID_ERROR = "Please enter Integer!"; public void AddError(string propertyName, string error) { if (!errors.ContainsKey(propertyName)) errors[propertyName] = new List<string>(); if (!errors[propertyName].Contains(error)) { errors[propertyName].Insert(0, error); RaiseErrorsChanged(propertyName); } } public void RemoveError(string propertyName, string error) { if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error)) { errors[propertyName].Remove(error); if (errors[propertyName].Count == 0) errors.Remove(propertyName); RaiseErrorsChanged(propertyName); } } public void RaiseErrorsChanged(string propertyName) { if (ErrorsChanged != null) ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); } #region INotifyDataErrorInfo Members public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; //对应上面的要点3 public System.Collections.IEnumerable GetErrors(string propertyName) { if (String.IsNullOrEmpty(propertyName) || !errors.ContainsKey(propertyName)) return null; return errors[propertyName]; } public bool HasErrors { get { return errors.Count > 0; } } #endregion }