如何在类中的类中的属性上使用INotifyPropertyChanged ..?

时间:2011-05-27 16:51:02

标签: c# wpf inotifypropertychanged

我的问题似乎是“范围”,但我不确定这是否是正确的术语。我想通知一个只读列表,以便在设置自定义对象中的属性时重新评估自己。我相信它根本不知道它的存在。也许有一个简单的方法,我想不到,但我画了一个空白。

我觉得这很难说,所以这里是简化的代码,我对我期望发生的事情发表评论。

我将数据绑定到的对象中的属性:

private CvarAspectRatios _aspectRatio = new CvarAspectRatios("none", GetRatio());
public CvarAspectRatios AspectRatio
{
    get { return _aspectRatio; }
    set
    {                                                 // This setter never gets hit since I bind to this 
        if (value != null)                            // object's 'Value' property now.
        {
            _aspectRatio = value;
            NotifyPropertyChanged("AspectRatio");
            NotifyPropertyChanged("ResolutionList");  // I want to inform ResolutionList
        }                                             // that it needs to repopulate based
    }                                                 // on this property: AspectRatio
}

private ResolutionCollection _resolutionList = ResolutionCollection.GetResolutionCollection();
public ResolutionCollection ResolutionList
{
   get 
   {
       ResolutionCollection list = new ResolutionCollection();
       if (AspectRatio != null && AspectRatio.Value != null)
       {
           foreach (Resolutions res in _resolutionList.Where(i => i.Compatibility == AspectRatio.Value.Compatibility))
           {
               list.Add(res);
           }
           return list;
       }
       return _resolutionList;
   }
}

CvarAspectRatios类:

public class CVarAspectRatios : INotifyPropertyChanged
{
    private string _defaultValue;
    public string DefaultValue
    {
        get { return _defaultValue; }
        set { _defaultValue = value; NotifyPropertyChanged("DefaultValue"); }
    }

    private AspectRatios _value;
    public AspectRatios Value
    {
        get { return _value; }
        set 
        { 
            _value = value; 
            NotifyPropertyChanged("Value"); 
            NotifyPropertyChanged("ResolutionList");  // This value gets set, and I'd like for ResolutionList to update
        }                                             // but it cannot find ResolutionList. No errors or anything. Just
    }                                                 // no update.

    public AspectRatios() { }

    public AspectRatios(string defaultValue, AspectRatios val)
    {
        DefaultValue = defaultValue;
        Value = val;
    }

    // Implementation of INotifyPropertyChanged snipped out here
}

你们有什么想法?如果您想要一个示例应用程序,我可以鞭打一个。

4 个答案:

答案 0 :(得分:3)

由于CVarAspectRatios实现了INotifyPropertyChanged,您可以让viewmodel类订阅AspectRatio的PropertyChanged事件。

public class YourViewModel 
{
    public YourViewModel()
    {
        AspectRatio.PropertyChanged += AspectRatio_PropertyChanged;
    }

    void AspectRatio_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Value")
            NotifyPropertyChanged("ResolutionList");
    }        
}

请记住,如果丢弃AspectRatio对象(如果对象引用发生更改而不仅仅是该对象的value属性),则应取消订阅被丢弃的对象。

答案 1 :(得分:2)

将现有代码转换为适用的代码:

private CvarAspectRatios _aspectRatio; //No field initialization because that would not attach event handler, you could do it though and take care of the handler alone in the ctor
public CvarAspectRatios AspectRatio
{
    get { return _aspectRatio; }
    set
    {
        if (_aspectRatio != value) // WTH @ "value != null"
        {
            _aspectRatio.PropertyChanged -= AspectRatio_PropertyChanged;
            _aspectRatio = value;
            _aspectRatio.PropertyChanged += new PropertyChangedEventHandler(AspectRatio_PropertyChanged);
            NotifyPropertyChanged("AspectRatio");
        }
    }
}

void AspectRatio_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Value")
    {
        NotifyPropertyChanged("ResolutionList");
    }
}

答案 2 :(得分:1)

为什么不将ResolutionList重新填充到一个单独的私有方法中,该方法是从AspectRatios的setter调用的?

答案 3 :(得分:0)

如果列表需要根据更改的属性进行更新,则列表(或列表管理器对象,以便更好地封装)通常需要订阅托管该属性的对象的PropertyChanged事件。如果列表本身是同一对象的属性,就像在这种情况下,属性的setter调用更新列表的方法会更简单和更精简。