我的问题似乎是"范围",尽管我不确定这是正确的术语。当设置了自定义对象中的属性时,我想通知只读列表重新评估其自身。我相信它根本没有意识到它的存在。也许有一种简单的方法可以解决这个问题,我想不出,但我还是一片空白。
我发现这很难用语言表达,所以下面是我对预期发生的事情的评论的简化代码。
数据绑定到的对象内的属性:
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
}
你们怎么想?如果你想要一个示例应用程序,我可以制作一个。
由于CVarAspectRatios实现了INotifyPropertyChanged,因此可以让视图模型类订阅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属性),那么您应该取消订阅被丢弃对象上的事件。
将现有代码转换为应该工作的代码:
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");
}
}
为什么不考虑将ResolutionList
重新填充到一个单独的私有方法中,该方法从AspectRatios
的setter调用?
如果列表需要根据更改的属性进行更新,则列表(或列表管理器对象,为了更好地封装)通常需要订阅托管该属性的对象的PropertyChanged事件。如果列表本身是同一对象的属性(如本例所示),那么属性的setter调用更新列表的方法会更简单、更精简。