L'associazione per un EntitySet visualizza valori che non esistono?
-
10-07-2019 - |
Domanda
Sto associando un ItemsControl a un EntitySet in un'applicazione WPF. Non si comporta come previsto, tuttavia. ItemsControl si comporta come se stesse memorizzando nella cache il contenuto dell'EntitySet tra i bind!
Ecco il codice ridotto :
L'entità:
public partial class Item : INotifyPropertyChanging, INotifyPropertyChanged
{
private EntitySet<Item> _Children;
public EntitySet<Item> Children {get{return _children;}}
/*...*/
}
La mia classe parziale:
public partial class Item
{
public void RemoveChild(Item child)
{
Children.Remove(child);
// this finds PropertyChanged; defined in the Entity class
SendPropertyChanged("Children");
}
}
L'interfaccia utente:
<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>
Codice che dimostra il comportamento (assume > 2 elementi, ognuno con un unico figlio):
this.ScrewyItem = Db.Items.First();
this.DataContext = ScrewyItem;
return;
Successivamente, rimuovo il figlio dall'entità:
ScrewyItem.RemoveChild(ScrewyItem.Children.First());
return;
Dopo l'esecuzione di questo codice, l'interfaccia utente non si aggiorna e viene mostrato che l'elemento ha tutti i figli. Nota che questo metodo chiama NotifyPropertyChanged, quindi i binding dovrebbero essere aggiornati!
Successivamente, rimuoviamo questo elemento dai collegamenti dell'interfaccia utente:
this.DataContext = Db.Items.Last(); //different item
return;
E poi associarlo nuovamente all'interfaccia utente più tardi
this.DataContext = ScrewyItem;
Supponendo che ALMENO a questo punto l'interfaccia utente mostrerebbe l'elenco figlio corretto. Questo è non il caso , tuttavia! Mostra la stessa lista di bambini come mostrato originariamente!
Ciò che è ancora più bizzarro, se inserisco un punto di interruzione nel mio accessore Bambini, posso vedere che si accede all'elenco quando mi ricollego all'interfaccia utente e l'elenco non contiene il bambino che ho rimosso.
L'unico modo in cui posso vedere che l'IU potrebbe fare questo è se il contenuto della raccolta Children viene memorizzato nella cache tra i bind.
Cosa sta succedendo qui? Cosa mi sto perdendo ???
Soluzione
Ho trovato una soluzione per questo. Fa un po 'schifo.
Posso avvolgere la collezione Children in una BindingList:
public IBindingList BindableChildren
{
get
{
return new BindingList<Item>(Children);
}
}
e quindi modifica il mio metodo RemoveChild in questo modo:
this.Children.Remove(arg);
SendPropertyChanged("BindableChildren");
Ciò comporta che l'interfaccia utente aggiorni immediatamente l'elenco e smette di mostrare il comportamento della memorizzazione nella cache.
La domanda rimane ancora: WTF? e Esiste un altro modo?
Altri suggerimenti
Non ne sono sicuro, ma forse ItemsControl
è in ascolto di eventi da IBindingList
o INotifyCollectionChanged
e non INotifyPropertyChanged
.