0

找到这个代码

这是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 实例,我们会得到:

  1. ValidationTemplate 已实例化 - 我假设因为我们将类型传递到此 ExtendWith 属性中,所以 .NET 会自动实例化该类型,但我无法在任何地方找到任何确认此行为的信息

  2. ValidationTemplate 目标属性被“神奇地”调用,它接收到对 PersonViewModel 的引用。哪个 .NET 行为片段调用了这个?我找不到任何描述此行为的文档 - 似乎它依赖于命名约定?还有其他可以填充的属性吗?这是什么魔法:)

  3. 如果此对象在 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 框架的一些内部/未记录的功能/黑客。

4

2 回答 2

1

该项目依赖于Hereder。花了我一整天的时间到处寻找,直到我检查 csproj 并看到构建后的任务。现在它是有道理的。

于 2013-04-22T01:20:05.517 回答
0

这里没有魔法。属性是 .NET 中一个有据可查的特性。属性本质上是关于可以添加的类的一些额外信息,可以通过反射访问。你可以在这里阅读更多关于它的信息。

编写良好的 MVVM 代码通常看起来很像“魔术”。实际上,通常有一个编写良好的框架,它使用反射和其他技巧来自动连接它。很可能很多实际工作都在 Caliburn.Micro.dll 或 FluentValidation.dll 中。这样你就可以编写一次引导逻辑,然后在你的所有 WPF/Silverlight/etc 上重用它。项目。除非您也有这些代码,否则您可以使用此处建议的反射器工具来查看它们,或者只是与 GitHub 存储库的所有者交谈,看看您是否也可以访问它们。

于 2013-04-21T22:19:38.383 回答