0

バインディングの中間層が変更されたときに PropertyChangedEvent をトリガーする方法を見つけようとしています。ここで例から始めます。

public class MainViewModel :NotificationObject // Main DataContext
{ 
   public SubViewModel SubVM{get; {_subVM = value; RaisePropertyChanged("SubVM");}}  // observable property
   public void DoChangeSubVM()
   {
      SubVM = new SubViewModel(); // doing this will not update the egControl
   }
}

public class SubViewModel : NotificationObject
{
   public Sub2ViewModel Sub2VM {get; set{_sub2VM = value; RaisePropertyChanged("Sub2VM");}} // observable property
}

public class Sub2ViewModel : NotificationObject
{
   public int SomeProp {get; set {_someProp = value; RaisePropertyChanged("SomeProp");} // observable property
}

XAML で:

<EgControl name="egControl" Content={Binding SubVM.Sub2VM.SomeProp} />

Sub2VM プロパティを変更しても、egControl は新しい Sub2VM インスタンスの SomeProp 値で自動的に更新されません。Sub2VM プロパティ セッターからすべての Sub2ViewModel propertychanged イベントを手動で発生させることなく、これを達成するにはどうすればよいでしょうか?

使用: Prism .NET 4.0

4

3 に答える 3

1

Sub2VM プロパティ セッターからすべての Sub2ViewModel propertychanged イベントを手動で発生させることなく、これを達成するにはどうすればよいでしょうか?

答え

いくつかの可能性があります:

あなたが避けたいと言った、セッターですべてのプロパティ変更イベントを発生させます。しかし、これは考慮すべき有効な戦略です。どのプロパティが別の結果に依存しているかがわかっている場合は、多くのプロパティのセッターで変更されたプロパティを発生させる必要があります。

public class myViewModel
{
    private string _FirstName
    public string FirstName
    {
        get { return_FirstName };
        set
        {
            _FirstName = value;
            RaisePropertyChanged("FirstName");
            RaisePropertyChanged("FullName");
        }
    }
}

新しい ViewModel が構築された後、メソッド内のすべてのプロパティ変更イベントを発生させます。

public class myViewModel
{
    private string _FirstName
    public string FirstName
    {
        get { return_FirstName };
        set
        {
            _FirstName = value;
            RaisePropertyChanged("FirstName");
        }
    }

    public void UpdateFirstName(string firstName)
    {
        _FirstName = firstName;
        RaisePropertyChanged("FirstName");
        RaisePropertyChanged("FullName");
    }
}

セッターを使用していくつかのプロパティを設定し、既存のプロパティ変更イベントをトリガーします。

public class myViewModel
{
    private string _FirstName
    public string FirstName
    {
        get { return_FirstName };
        set
        {
            _FirstName = value;
            RaisePropertyChanged("FirstName");
        }
    }

    public Person ClonePerson(Person rootPerson)
    {
        Person clone = new Person()
        {
            FirstName = rootPerson.FirstName;
            LastName = rootPerson.LastName;
        }
        return clone;
    }
}

すべてのプロパティ変更イベントを発生させるメソッドを作成し、複数の変更イベントを発生させる必要があるエッジ ケースでそれを呼び出します。

public class myViewModel
{
    private string _FirstName
    public string FirstName
    {
        get { return_FirstName };
        set
        {
            _FirstName = value;
            this.RaiseAllPropertyChanges();
        }
    }

    public void RaiseAllPropertyChanges()
    {
        RaisePropertyChanged("FirstName");
        RaisePropertyChanged("FullName");
    }
}

最終結果は次のとおりです。バインドされた UI 要素が更新する必要があることを知るには、そのプロパティのプロパティ変更イベントを発生させる必要があります。

于 2012-05-15T20:19:29.430 に答える
0

Prism についてはわかりませんが、一般的に言えば、3 つのクラスすべてがプロパティ変更通知を実装する必要があります。これを行う最も簡単な方法は、INotifyPropertyChanged を使用することです。したがって、SubViewModel は次のようになります。

public class SubViewModel : INotifyPropertyChanged
{ 
    private Sub2ViewModel sub2vm;
    public Sub2ViewModel Sub2VM 
    {
        get
        {
            return sub2vm;
        }
        set
        {
            sub2vm = value;
            OnPropertyChanged("Sub2VM");
        }
    }

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
} 

プロパティの変更通知がないと、UI はバインドされたプロパティを更新するタイミングを認識できません。

于 2012-05-15T19:06:07.383 に答える
0

これを行う 1 つの方法は、SubViewModel と Sub2ViewModel の両方のコンストラクターを作成して、すべてのプロパティを何らかの既定値に初期化することです。これにより、プロパティが確実に初期化され、初期値を設定できるようになります。

于 2012-05-15T23:40:02.760 に答える