找到这个代码
这是gyst:
视图模型:
[ExtendWith(typeof(ValidationTemplate))]
public class PersonViewModel :INotifyPropertyChanged
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
ExtendWithAttribute
public class ExtendWithAttribute : Attribute
{
public ExtendWithAttribute(Type type)
{
}
}
验证模板
public class ValidationTemplate : IDataErrorInfo
{
private INotifyPropertyChanged target;
public object Target
{
get
{
return target;
}
set
{
target = (INotifyPropertyChanged)value;
validator = ValidationFactory.GetValidator(target.GetType());
validationResult = validator.Validate(Target);
target.PropertyChanged += Validate;
}
}
private void Validate(object sender, PropertyChangedEventArgs e)
{
if (validator != null)
{
validationResult = validator.Validate(target);
}
}
private IValidator validator;
private ValidationResult validationResult;
public string Error
{
get
{
return string.Join(Environment.NewLine, validationResult.Errors.Select(x => x.ErrorMessage).ToArray());
}
}
public string this[string propertyName]
{
get
{
return string.Join(Environment.NewLine, validationResult.Errors.Where(x => x.PropertyName == propertyName).Select(x => x.ErrorMessage).ToArray());
}
}
}
如果我们创建一个 PersonViewModel 实例,我们会得到:
ValidationTemplate 已实例化 - 我假设因为我们将类型传递到此 ExtendWith 属性中,所以 .NET 会自动实例化该类型,但我无法在任何地方找到任何确认此行为的信息
ValidationTemplate 目标属性被“神奇地”调用,它接收到对 PersonViewModel 的引用。哪个 .NET 行为片段调用了这个?我找不到任何描述此行为的文档 - 似乎它依赖于命名约定?还有其他可以填充的属性吗?这是什么魔法:)
如果此对象在 XAML 中绑定,则验证正常工作,但 ViewModel 不直接实现IDataErrorInfo,这是 WPF 挂钩以使其验证工作的原因。然而它可以工作,不知何故它能够从某个地方使用这个 ValidationTemplate 任意对象。
更新:所以在我在调试器中检查了 PersonViewModel 之后,得到了以下有趣的答案:
var viewModel = new PersonViewModel();
var isDataErrorInfo = viewModel is IDataErrorInfo; // true
var isDataErrorInfo = viewModel is ValidationTemplate; // false
该代码基于 Caliburn.Micro,引导程序是香草,其中没有任何内容。我手动实例化了 PersonViewModel 以确认调用扩展程序类的不是 WPF 特定行为,并且我确实在 Target 属性触发时获得了 setter/getter。
有人可以解释所有这些奇怪的行为吗?我有一种感觉,这是 .NET 框架的一些内部/未记录的功能/黑客。