私のシナリオ: 2 つの異なる ObervableCollections にバインドされた 2 つの ListBox があります。形状のコレクションと色のコレクションであり、属性条件が一致する部品番号を見つけるためにユーザーが選択できます。(私のアプリにはさらに多くの属性コレクションが存在しますが、わかりやすくするために省略しています。)
属性値を含む 2 つのリストボックスのいずれかから選択すると、選択した属性プロパティを持つ結果のパーツ番号が というコレクションに収集されResultingPNsIntersect
ます。(結果の部品番号のコレクションは、3 番目の ListBox に表示されます。)
何が起こるか: 2 つのリストボックスのいずれかで選択を行った後、Selected'Attribute' を持つ結果の部品番号の共通部分が更新され、関連する部品番号のみが残るようになります。形状が選択されている場合、 を保持するリストボックスを更新して、 を持つ PartNumbers に関連するColorsCollection
色属性 ( 内) のみが 2 番目のリストボックスに表示されるようにする必要があります。ColorsCollection
SelectedShape
私の問題:形状を選択した後、ResultingPNsIntersect ObservableCollection
更新されますが、PropertyChanged 通知ColorsCollection
が発生しないため、2 番目のリストボックスが更新されず、ユーザーが選択できる更新された色属性が提供されません。
以前、他のアプリでこれを行ったことがありますが、問題はありません。ResultingPNsIntersect のプロパティ値を編集していないため、サブスクライブする必要はありCollectionChanged
ません。コレクションを新しい値に置き換えています。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}"/>
私のビューモデル:
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
ます。ResultingPNsIntersect
ただし、AvailableColorsCollection は、属性リストボックスでの選択に基づいて変化する Collection に依存しているため、当然、あまり意味がありません。