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 ???

È stato utile?

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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top