找到 this code
这是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)
{
}
}
ValidationTemplate
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 Target属性正在“神奇地”调用,它接收对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,引导程序是vanilla,其中没有任何内容。我手动实例化PersonViewModel以确认它不是调用extender类的WPF特定行为,并且我确实在Target属性触发时得到了setter / getter。
有人可以解释所有这些奇怪的行为。我有一种感觉,这是.NET框架的一些内部/未记录的功能/黑客。
答案 0 :(得分:1)
该项目依赖于Hereder。整天都在寻找我,直到我检查csproj并看到后期构建任务。现在它是有道理的。
答案 1 :(得分:0)
这里没有魔力。属性是.NET中记录良好的特性。属性本质上是一些关于可以添加的类的额外信息,可以通过反射访问。您可以阅读更多相关信息here。
编写良好的MVVM代码通常看起来很像“魔术”。实际上,通常有一个编写良好的框架,它使用反射和其他技巧来自动连接它。很可能很多实际工作都是在Caliburn.Micro.dll或FluentValidation.dll中完成的。这样你就可以编写一次bootstrap逻辑,只需在你的所有WPF / Silverlight /等上重复使用它。项目。除非您有这些代码,否则您可以使用像建议here那样的反射器工具来查看它们,或者只是与GitHub仓库的所有者交谈,看看您是否也可以访问这些代码。