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 事件?

使用:棱镜 .NET 4.0

4

3 回答 3

1

有人如何实现这一点,而无需手动从 Sub2VM 属性设置器中引发所有 Sub2ViewModel propertychanged 事件?

回答

你有几种可能性:

在 setter 中引发所有属性更改事件,您说过要避免这些事件。但这是一个值得考虑的有效策略。如果您知道哪些属性依赖于另一个属性的结果,那么它们将需要在 setter 中为许多属性引发属性更改。

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");
    }
}

使用 setter 设置一些属性,从而触发已经存在的属性更改事件。

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

一种方法是为 SubViewModel 和 Sub2ViewModel 创建一个构造函数,将所有属性初始化为某个默认值。这将确保您的属性已初始化并让您能够设置初始值。

于 2012-05-15T23:40:02.760 回答
0

好的,不确定 Prism,但一般来说,所有三个类都应该实现属性更改通知。最简单的方法是使用 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 回答