8,737
社区成员
发帖
与我相关
我的任务
分享
public class AgeRule
{
[Required]
[Display(Name = "用户名")]
[StringLength(100, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = 6)]
public string UserName { get; set; }
}
public class User : PropertyChangedNotification
{
[Required(ErrorMessage = "名称不能为空")]
[MaxLength(10, ErrorMessage = "名称最多10位数")]
[MinLength(4, ErrorMessage = "名称最少4位数")]
public string number
{
get { return GetValue(() => number); }
set { SetValue(() => number, value); }
}
}
//这是ViewModel
public class UserViewModel : PropertyChangedNotification
{
private static UserViewModel userViewModel;
public User NewUser
{
get { return GetValue(() => NewUser); }
set { SetValue(() => NewUser, value); }
}
public static int Errors { get; set; }
/// <summary>
/// 加载时用
/// </summary>
/// <returns></returns>
public static UserViewModel SharedViewModel()
{
return userViewModel ?? (userViewModel = new UserViewModel());
}
private UserViewModel()
{
NewUser = new User();
}
}
下面直接在窗口放一个TEXTBOX和TEXTBLOCK就行了
<Grid x:Name="grdUser" DataContext="{Binding NewUser, ValidatesOnDataErrors=True}">
<TextBox x:Name="TxtName" HorizontalAlignment="Left" Height="23" Margin="144,114,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"
Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,NotifyOnValidationError=True}" Validation.Error="Validation_Error" />
<TextBlock HorizontalAlignment="Left" Margin="288,115,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="80"
Text="{Binding (Validation.Errors)[0].ErrorContent, ElementName=TxtName}" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="144,173,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
</Grid>
后台
public MainWindow()
{
InitializeComponent();
this.DataContext = UserViewModel.SharedViewModel();
this.Loaded += Window_Loaded;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var errors = grdUser.GetValue(Validation.ErrorsProperty);
}
private void Validation_Error(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added) UserViewModel.Errors += 1;
if (e.Action == ValidationErrorEventAction.Removed) UserViewModel.Errors -= 1;
}
好了大功告成。以便后用,就是有点吃不透,如果哪位有空也请帮我分析一下谢谢楼上指点
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;// 包含了能够与系统进程 事件日志 和性能计数器进行交互的类 一般用于帮助诊断和调试应用程序
using System.Linq.Expressions;
using System.ComponentModel.DataAnnotations;
namespace HaiTunWpf.Notification
{
/// <summary>
/// 属性更改通知类
/// </summary>
public class PropertyChangedNotification : INotifyPropertyChanged, IDataErrorInfo
{
#region Fields
private readonly Dictionary<string, object> _values = new Dictionary<string, object>();
#endregion
#region Protected
/// <summary>
/// 设置一个属性的值.
/// </summary>
/// <typeparam name="T">属性值的类型.</typeparam>
/// <param name="propertySelector">表达式树包含属性定义.</param>
/// <param name="value">属性值.</param>
protected void SetValue<T>(Expression<Func<T>> propertySelector, T value)
{
string propertyName = GetPropertyName(propertySelector);
SetValue<T>(propertyName, value);
}
/// <summary>
/// 设置一个属性的值.
/// </summary>
/// <typeparam name="T">属性值的类型</typeparam>
/// <param name="propertyName">属性的名称.</param>
/// <param name="value">属性值.</param>
protected void SetValue<T>(string propertyName, T value)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("无效的属性名", propertyName);
}
_values[propertyName] = value;
NotifyPropertyChanged(propertyName);
}
/// <summary>
/// 获取一个属性的值。
/// </summary>
/// <typeparam name="T">属性值的类型.</typeparam>
/// <param name="propertySelector">表达式树包含属性定义。</param>
/// <returns>如果为空则返回默认值.</returns>
protected T GetValue<T>(Expression<Func<T>> propertySelector)
{
string propertyName = GetPropertyName(propertySelector);
return GetValue<T>(propertyName);
}
/// <summary>
/// 获取一个属性的值.
/// </summary>
/// <typeparam name="T">属性值的类型.</typeparam>
/// <param name="propertyName">属性的名称.</param>
/// <returns>如果为空则返回默认值.</returns>
protected T GetValue<T>(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("无效的属性名", propertyName);
}
object value;
if (!_values.TryGetValue(propertyName, out value))
{
value = default(T);
_values.Add(propertyName, value);
}
return (T)value;
}
/// <summary>
/// 验证当前实例属性使用数据
/// </summary>
/// <param name="propertyName">验证实例属性名称</param>
/// <returns>有关错误字符串验证失败 or <see cref="System.String.Empty"/> 验证成功.</returns>
protected virtual string OnValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("无效的属性名", propertyName);
}
string error = string.Empty;
var value = GetValue(propertyName);
var results = new List<System.ComponentModel.DataAnnotations.ValidationResult>(1);
var result = Validator.TryValidateProperty(
value,
new ValidationContext(this, null, null)
{
MemberName = propertyName
},
results);
if (!result)
{
var validationResult = results.First();
error = validationResult.ErrorMessage;
}
return error;
}
#endregion
#region Change Notification
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 提出了这个对象的PropertyChanged事件.
/// </summary>
/// <param name="propertyName">一个新值的属性</param>
protected void NotifyPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
protected void NotifyPropertyChanged<T>(Expression<Func<T>> propertySelector)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
string propertyName = GetPropertyName(propertySelector);
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion // INotifyPropertyChanged Members
#region Data Validation
string IDataErrorInfo.Error
{
get
{
throw new NotSupportedException("不支持使用IDataErrorInfo。这个[propertyName].");
}
}
string IDataErrorInfo.this[string propertyName]
{
get
{
return OnValidate(propertyName);
}
}
#endregion
#region Privates
private string GetPropertyName(LambdaExpression expression)
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
{
throw new InvalidOperationException();
}
return memberExpression.Member.Name;
}
private object GetValue(string propertyName)
{
object value;
if (!_values.TryGetValue(propertyName, out value))
{
var propertyDescriptor = TypeDescriptor.GetProperties(GetType()).Find(propertyName, false);
if (propertyDescriptor == null)
{
throw new ArgumentException("无效的属性名", propertyName);
}
value = propertyDescriptor.GetValue(this);
_values.Add(propertyName, value);
}
return value;
}
#endregion
#region Debugging 调试助手
/// <summary>
/// 如果这个对象没有警告
/// 开发人员说
///指定名称方法不存在在一份构建
/// </summary>
[Conditional("DEBUG")]//引用System.Diagnostics;
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// 验证属性名匹配是否正确。
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "无效的属性名: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
///返回是否抛出异常,或者使用Debug.Fail()
/// 当一个无效的属性名称传递给VerifyPropertyName方法
/// 默认值是错误的,但是子类可能使用的单元测试
/// 覆盖这个属性的getter返回true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // 调试助手
}
}