Die Umsetzung einer ListView mit einer CollectionViewSource - Nicht Erfrischend?
Arbeite ich am Aufbau einer ListView, deren Source
- Eigenschaft auf eine ivar von einer Klasse von mir, genannt Cat
.
Jeder Cat
hat eine ObservableCollection
von Trait
Objekte:
private ObservableCollection<Trait> _traits = new ObservableCollection<Trait>();
public ObservableCollection<Trait> Traits
{
get
{
return _traits;
}
}
public void AddTrait(Trait t)
{
_traits.Add(t);
//Is this redundant? Is one better than the other?
this.OnPropertyChanged("_traits");
this.OnPropertyChanged("Traits");
}
public IEnumerator<Object> GetEnumerator()
{
return _traits.GetEnumerator();
}
Ist und dann bin ich die Zuordnung der Source
Eigenschaft dieser Traits
Sammlung:
this.CollectionViewSource.Source = CurrentCat.Traits;
Dies korrekt funktioniert, und die Trait
Objekte werden richtig angezeigt in meinem ListView
.
Das Problem ist, dass änderungen dieser zugrunde liegenden _traits
Sammlung nicht bewirken, dass das UI richtig aktualisiert. Zum Beispiel diese:
void AddTraitButton_Click(object sender, RoutedEventArgs e)
{
if (this.CurrentCat != null)
{
this.CurrentCat.AddTrait(new Trait());
}
}
Nicht scheinen, um eine Wirkung sofort in der Benutzeroberfläche, aber wenn ich einen reset der Source
- Eigenschaft, etwa so:
var oldSource = this.CollectionViewSource.Source;
this.CollectionViewSource.Source = null;
this.CollectionViewSource.Source = oldSource;
Dann die ListView
korrekt aktualisiert. Aber ich bin sicher, es muss etwas sein, das mir fehlt, wie ich möchte, dass das UI-update auf die addition/entfernen einer Sache.
Edit: Die CollectionViewSource
angewendet wird, um die ListView
in meiner XAML-Datei:
<CollectionViewSource x:Name="CollectionViewSource" x:Key="CollectionViewSource" />
...
<ListView x:Name="ItemListView" ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" ...
- Wie ist die CollectionViewSource gesetzt, um die ListView?
- Hinzugefügt.
- In Bezug auf die "Ist das überflüssig? Ist einer besser als der andere?" - Kommentar:
_traits
ist eine private-Mitglied sind und nicht übergeben werden müssen, umOnPropertyChanged
- nachdem alle, es könnte nicht alles, was gebunden ist an die update-Benachrichtigung erhalten.OnPropertyChanged("Traits");
genügt. - Danke, das hilft klären die Dinge.
- diese.OnPropertyChanged("Traits"); Verwenden Sie dies auf Ihr Kommentar über, was besser ist, und nur wenn, wenn Sie tun, eine Bindung wie es aussieht {Binding Merkmale} und das gebundene Objekt DataContext gesetzt ist, um das Objekt mit den Eigenschaften Eigenschaft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sehen Sie sich diese demo, die ich in Aufmachungen in Bezug auf erste ListView-Bindung verknüpft und arbeiten für alle CRUD-Operationen.
http://www.flaskofespresso.com/2012/01/windows-8-metro-app-listview-binding-and-editing/
Ich kann nicht scheinen zu finden es jetzt, aber ich glaube mich zu erinnern einige Probleme mit der Bindung zu
CollectionViewSource
. Haben Sie versucht, binden direkt anCurrentCat.Traits
und Einstellungthis.DataContext = this
im code-behind (ich gehe davon aus, dass Sie nicht mit MVVM hier)?this.DataContext = this
im code-behind-load Abschnitt. Sehen, ob das funktioniert.Eher als die Bindung an die CollectionViewSource direkt und ersetzt seine
Source
um eine Aktualisierung erzwingen, ich glaube, Sie wollen, binden sich an den CVS istView
Eigenschaft......und rufen
CollectionViewSource.Refresh()
nach dem Update der source-Sammlung.Auch, ein paar Hinweise, da Sie scheinen relativ neu zu .NET/WPF-Konventionen:
this
Schlüsselwort ist in der Regel überflüssig, es sei denn, es gibt einen anderen Bezeichner, der Bereich mit dem gleichen NamenLohnt es sich, die Erkundung der MVVM und der damit verbundenen Muster, wenn Sie etwas zu tun, nicht-triviale in WPF; Sie helfen Ihnen, Ihre Ansichten (XAML-Objekte), die als Licht und leicht zu ändern wie möglich.
In Ihrem Fall, zum Beispiel, ich nehme den code, den Sie gezeigt haben, ist von der code-hinter jedem Fenster-oder Benutzersteuerelement enthält deine ListView. Nach dem MVVM-Muster würde sich um die Erstellung eines separaten "ViewModel" - Klasse, die enthält die
Traits
Sammlung und setzen es über eineCollectionViewSource
(verwenden Sie die View-Eigenschaft, wie ich bereits erwähnt habe). Ihr Benutzersteuerelement würde dann eine Instanz von der ViewModel zugewiesen als seineDataContext
, und die ListView könnte gebunden werden, ausgesetzt CollectionView.View
Eigentum meinesCollectionViewSource
keinenRefresh()
MethodeCollectionViewSource.View
- Eigenschaft ist vom TypICollectionView
, die hat in der Tat eine Refresh () - Methode... Wenn Sie debug und Pause in das Click-Ereignis, wiethis.CollectionViewSource
's View-Eigenschaft definiert?Können Sie arbeiten ausschließlich mit der ObservableCollection noch. Obwohl es ein problem ist - wäre es nicht angezeigt, die Daten in IsInDesignMode. Vielleicht wird es in Zukunft zu verbessern.