このコードを見つけました
ここに要点があります:
ビューモデル:
[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 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 に基づいており、bootstrapper は何も入っていないバニラです。PersonViewModel を手動でインスタンス化して、エクステンダー クラスを呼び出すのが WPF 固有の動作ではないことを確認し、Target プロパティの起動時にセッター/ゲッターを取得しました。
誰かがこれらすべての奇妙な行動を説明してもらえますか. これは、.NET フレームワークの内部/文書化されていない機能/ハッキングであると感じています。