0

このコードを見つけました

ここに要点があります:

ビューモデル:

[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 Target プロパティが「魔法のように」呼び出され、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 に基づいており、bootstrapper は何も入っていないバニラです。PersonViewModel を手動でインスタンス化して、エクステンダー クラスを呼び出すのが WPF 固有の動作ではないことを確認し、Target プロパティの起動時にセッター/ゲッターを取得しました。

誰かがこれらすべての奇妙な行動を説明してもらえますか. これは、.NET フレームワークの内部/文書化されていない機能/ハッキングであると感じています。

4

2 に答える 2

1

プロジェクトはHerederに依存しています。csproj をチェックしてビルド後のタスクが表示されるまで、一日中あちこちを探していました。今では理にかなっています。

于 2013-04-22T01:20:05.517 に答える
0

ここで起こっている魔法はありません。属性は、.NET のよく文書化された機能です。属性は基本的に、リフレクションを介してアクセスされる、追加できるクラスに関する追加情報です。詳細については、こちらをご覧ください。

よく書かれた MVVM コードは、通常、「魔法」のように見えます。実際には、通常、リフレクションやその他のトリックを使用して自動的に接続する適切に作成されたフレームワークがあります。ほとんどの場合、これらすべてを実行するための実際の作業の多くは、Caliburn.Micro.dll または FluentValidation.dll にあります。そうすれば、ブートストラップ ロジックを 1 回記述するだけで、すべての WPF/Silverlight/etc で再利用できます。プロジェクト。それらのコードも持っていない限り、ここで提案されているようなリフレクター ツールを使用してそれらを調べるか、GitHub リポジトリの所有者と話をして、それらにもアクセスできるかどうかを確認してください。

于 2013-04-21T22:19:38.383 に答える