ItemsControlをWPFアプリケーションのEntitySetにバインドしています。ただし、期待どおりに機能していません。ItemsControlは、バインド間でEntitySetのコンテンツをキャッシュしているように動作します。
これが簡略化されたコードです:
エンティティ:
public partial class Item : INotifyPropertyChanging, INotifyPropertyChanged
{
private EntitySet<Item> _Children;
public EntitySet<Item> Children {get{return _children;}}
/*...*/
}
私の部分的なクラス:
public partial class Item
{
public void RemoveChild(Item child)
{
Children.Remove(child);
// this finds PropertyChanged; defined in the Entity class
SendPropertyChanged("Children");
}
}
UI:
<ItemsControl
Name="ItemChildren"
Background="CornflowerBlue"
ItemsSource="{Binding Children}">
<ItemsControl.ItemTemplate>
<DataTemplate
DataType="{x:Type d:Item}">
<DockPanel>
<TextBlock
Text="{Binding Name}/>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
動作を示すコード(2つ以上のアイテムを想定し、それぞれに1つの子があります)。
this.ScrewyItem = Db.Items.First();
this.DataContext = ScrewyItem;
return;
後で、エンティティから子を削除します。
ScrewyItem.RemoveChild(ScrewyItem.Children.First());
return;
このコードが実行された後、UIは更新されず、アイテムにはすべての子が表示されます。このメソッドはNotifyPropertyChangedを呼び出すため、バインディングが更新されることに注意してください。
後で、このアイテムをUIバインディングから削除します。
this.DataContext = Db.Items.Last(); //different item
return;
そして、後でもう一度UIにバインドします
this.DataContext = ScrewyItem;
この時点で、少なくともUIに正しい子リストが表示されると想定します。 ただし、これは当てはまりません。最初に表示されたのと同じ子のリストが表示されます。
さらに奇妙なことに、Childrenアクセサーにブレークポイントを設定すると、UIに再バインドしたときにリストにアクセスし、 削除した子がリストに含まれていないことがわかります。
UIがこれを実行できることを確認できる唯一の方法は、Childrenコレクションのコンテンツがバインド間でキャッシュされている場合です。
ここで何が起こっているのですか?私は何が欠けていますか?