Ligação para um EntitySet está exibindo valores que não estão lá?
-
10-07-2019 - |
Pergunta
Estou vincular um ItemsControl a um EntitySet em um aplicativo WPF. A sua não agir como esperado, no entanto. O ItemsControl está se comportando como se fosse cache o conteúdo do EntitySet entre liga!
Aqui está o código despojado :
A entidade:
public partial class Item : INotifyPropertyChanging, INotifyPropertyChanged
{
private EntitySet<Item> _Children;
public EntitySet<Item> Children {get{return _children;}}
/*...*/
}
A minha classe parcial:
public partial class Item
{
public void RemoveChild(Item child)
{
Children.Remove(child);
// this finds PropertyChanged; defined in the Entity class
SendPropertyChanged("Children");
}
}
A interface do usuário:
<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>
Código que demonstra o comportamento (assumir> 2 Itens, cada um com uma única criança):
this.ScrewyItem = Db.Items.First();
this.DataContext = ScrewyItem;
return;
Mais tarde, eu remover a criança da entidade:
ScrewyItem.RemoveChild(ScrewyItem.Children.First());
return;
Após esse código é executado, a UI não atualiza eo item é mostrado para ter todas as crianças. Note que este método chamadas NotifyPropertyChanged, então as ligações devem atualizar!
Mais tarde, remover este item as ligações de interface do usuário:
this.DataContext = Db.Items.Last(); //different item
return;
E, em seguida, vinculá-lo à UI novamente mais tarde
this.DataContext = ScrewyItem;
Você diria que, pelo menos neste momento a interface do usuário irá mostrar a lista de filhos correta. Esta é não o caso , no entanto! Ele mostra o mesma lista de crianças como originalmente período!
O que é ainda mais bizarro, se eu colocar um ponto de interrupção no meu acessor Crianças, eu posso ver que lista é acessada quando eu religar à UI e a lista não contém a criança que eu removido.
A única maneira que eu posso ver que a interface do usuário poderia estar fazendo isso é se o conteúdo da coleção Crianças são armazenados em cache entre liga.
O que está acontecendo aqui? O que estou ausente ???
Solução
Eu encontrei uma solução para isso. É o tipo de porcaria.
Eu posso envolver a coleção Crianças em um BindingList:
public IBindingList BindableChildren
{
get
{
return new BindingList<Item>(Children);
}
}
e, em seguida, modificar o meu método RemoveChild assim:
this.Children.Remove(arg);
SendPropertyChanged("BindableChildren");
Isso resulta na UI de atualização da lista imediatamente e pára exibindo o comportamento de cache.
A questão ainda Remans:? WTF e Existe outra maneira
Outras dicas
Eu não tenho certeza sobre isso, mas talvez o ItemsControl
está ouvindo eventos de IBindingList
ou INotifyCollectionChanged
e não INotifyPropertyChanged
.