【发布时间】:2013-08-09 19:14:26
【问题描述】:
我的 Senario: 我有两个 ListBox 绑定到两个不同的 ObervableCollections - 一个形状集合和一个颜色集合,用户可以从中选择以查找具有匹配属性标准的部件号。 (我的应用中存在更多属性集合,但为了清楚起见,我将它们省略了。)
在从两个包含属性值的列表框中进行选择后,我会在名为ResultingPNsIntersect 的集合中收集拥有所选属性属性的结果部件号。 (结果部件号的集合显示在第三个 ListBox 中。)
应该发生什么:在两个列表框中的任何一个中进行选择后,拥有 Selected'Attribute' 的结果部件号的交集应该更新,以便只有相关零件编号保持不变。如果选择了一个形状,则包含 ColorsCollection 的列表框必须更新,以便只有与具有 SelectedShape 的 PartNumber 相关的颜色属性(在 ColorsCollection 中)显示在第二个列表框中。
我的问题: 选择形状后,ResultingPNsIntersect ObservableCollection 会更新,但不会触发 ColorsCollection 的 PropertyChanged 通知,因此第二个列表框永远不会更新以向用户提供更新的颜色属性从中选择。
我之前在其他应用程序中也这样做过,没有任何问题。我认为没有必要订阅CollectionChanged,因为我没有在 ResultingPNsIntersect 中编辑属性值——我正在用新值替换集合。请帮我看看我的代码在哪里失败以及原因,以便我更好地了解 INPC 触发所需的条件。
xaml 绑定:
<ListBox x:Name="SelectFromAvailableShapesLB" DockPanel.Dock="Top"
ItemsSource="{Binding AvailableShapesCollection}"
DisplayMemberPath="AttVal"
SelectedItem="{Binding SelectedShape, Mode=TwoWay}"/>
<ListBox x:Name="SelectFromAvailableColorsLB" DockPanel.Dock="Top"
ItemsSource="{Binding AvailableColorsCollection}"
DisplayMemberPath="AttVal"
SelectedItem="{Binding SelectedColor, Mode=TwoWay}"/>
<ListBox x:Name="PnsResultingFromAttributeSelectionsLB" DockPanel.Dock="Top"
ItemsSource="{Binding ResultingPNsIntersect}"
DisplayMemberPath="PartNum"
SelectedItem="{Binding SelectedPartNum, Mode=TwoWay}"/>
我的 ViewModel:
public ObservableCollection<AttributeValuesLibrary> AvailableShapesCollection
{
get
{
if (_resultingPNsIntersect != null)
{
foreach (PartNumber shape in _resultingPNsIntersect.Where(x => x.ShapeID != null))
{
if (!_availableShapesCollection.Contains(shape.AttributeValuesLibrary_Shape))
{
this._availableShapesCollection.Add(shape.AttributeValuesLibrary_Shape);
}
}
}
return _availableShapesCollection;
}
set
{
if (_availableShapesCollection != value)
{
this._availableShapesCollection = value;
RaisePropertyChanged("AvailableShapesCollection");
}
}
}
public ObservableCollection<AttributeValuesLibrary> AvailableColorsCollection
{
get
{
if (_resultingPNsIntersect != null)
{
foreach (PartNumber color in _resultingPNsIntersect.Where(x => x.ColorID != null))
{
if (!_availableColorsCollection.Contains(color.AttributeValuesLibrary_Color))
{
_availableColorsCollection.Add(color.AttributeValuesLibrary_Color);
}
}
}
return _availableColorsCollection;
}
set
{
if (_availableColorsCollection != value)
{
_availableColorsCollection = value;
RaisePropertyChanged("AvailableColorsCollection");
}
}
}
public AttributeValuesLibrary SelectedShape
{
get
{
return _selectedShape;
}
set
{
if (_selectedShape != value)
{
_selectedShape = value;
RaisePropertyChanged("SelectedShape");
RaisePropertyChanged("ResultingPNsIntersect");
}
}
}
public ObservableCollection<ConnectorPartNumber> ConnAttPNResults
{
get
{
// If a shape has been selected, we need to navigate to it's related PartNumbers and add those to the intersection
// contained by ResultingPNsIntersection.
if (_selectedShape != null)
{
var shapeResults = _context.PartNumbers.Where(x => x.AttributeValuesLibrary_Shape.AttValID == _selectedShape.AttValID);
if (_resultingPNsIntersect != null)
{
var resultsFromPreviousSelection = _resultingPNsIntersect;
_resultingPNsIntersect = new ObservableCollection<PartNumber>(resultsFromPreviousSelection.Intersect(shapeResults));
}
else if (_resultingPNsIntersect == null)
{
_resultingPNsIntersect = new ObservableCollection<PartNumber>(shapeResults);
}
}
return _resultingPNsIntersect;
}
set
{
if (_resultingPNsIntersect != value)
{
this._resultingPNsIntersect = value;
RaisePropertyChanged("ResultingPNsIntersect");
RaisePropertyChanged("AvailableColorsCollection"); <--Not firing!!!!!
}
}
}
提前致谢!
::UPDATE:: 如果我将RaisePropertyChanged("AvailableColorsCollection") 放在我的SelectedShape 的设置器中,我可以强制它工作。但是,当然,它在那里意义不大,因为 AvailableColorsCollection 依赖于 ResultingPNsIntersect 集合,该集合会根据属性列表框中的选择而变化。
【问题讨论】:
标签: c# wpf mvvm observablecollection inotifypropertychanged