Wie Implementieren einer ListBox Checkboxen in WPF?
Obwohl etwas erfahren mit dem schreiben von Winforms-Anwendungen, die... "Unbestimmtheit" des WPF-noch entzieht sich mir in Bezug auf best practices und design-patterns.
Trotz Auffüllen meiner Liste zur Laufzeit, meine listbox leer angezeigt.
Habe ich befolgte die einfachen Anweisungen, die von diesen Artikel hilfreich ohne Erfolg. Ich vermute, dass was mir fehlt, ist irgendeine Art von DataBind()
Methode, wo ich sage das Listenfeld, das ich fertig bin ändern der zugrunde liegenden Liste.
In meiner MainWindow.xaml habe ich:
<ListBox ItemsSource="{Binding TopicList}" Height="177" HorizontalAlignment="Left" Margin="15,173,0,0" Name="listTopics" VerticalAlignment="Top" Width="236" Background="#0B000000">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In meinem code-behind habe ich:
private void InitializeTopicList( MyDataContext context )
{
List<Topic> topicList = ( from topic in context.Topics select topic ).ToList();
foreach ( Topic topic in topicList )
{
CheckedListItem item = new CheckedListItem();
item.Name = topic.DisplayName;
item.ID = topic.ID;
TopicList.Add( item );
}
}
Die durch die Verfolgung durch, ich weiß, wird aufgefüllt mit vier Elementen.
BEARBEITEN
Habe ich geändert TopicList
zu einem ObservableCollection
. Es funktioniert immer noch nicht.
public ObservableCollection<CheckedListItem> TopicList;
EDIT #2
Habe ich zwei änderungen vorgenommen, die helfen:
In der .der xaml-Datei:
ListBox ItemsSource="{Binding}"
In den source-code, nachdem ich die Liste füllen:
listTopics.DataContext = TopicList;
Ich bin immer in der Liste, aber es ist nicht automatisch aktualisieren das Kontrollkästchen Staaten, wenn ich aktualisieren diese. Ich vermute, ein wenig weiter Lesen auf mein Teil wird dieses Problem beheben.
InformationsquelleAutor der Frage Bob Kaufman | 2010-12-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden
ObservableCollection<Topic>
stattList<Topic>
Bearbeiten
implementiert INotifyCollectionChanged-Schnittstelle lassen WPF wissen, wenn Sie hinzufügen/entfernen/ändern von Elementen
Edit 2
Da legen Sie
TopicList
im code, es sollte eine Abhängigkeit der Eigenschaft, nicht ein gemeinsames FeldEdit 3
Änderungen in Artikel
INotifyPropertyChanged
SchnittstelleCheckedListItem
(jede setter-aufrufen solltenPropertyChanged(this, new PropertyChangedEventArgs(<property name as string>))
event)CheckedListItem
ausDependencyObject
und konvertierenName
,ID
,IsChecked
dependency propertiestopicList[0] = new CheckedListItem() { Name = ..., ID = ... }
)InformationsquelleAutor der Antwort Mykola Bogdiuk
Vorausgesetzt
TopicList
ist nicht einObservableCollection<T>
daher, wenn Sie Elemente hinzufügen keineINotifyCollection
geändert wird gefeuert zu sagen, die Bindung Motor um den Wert zu aktualisieren.Ändern Sie Ihre
TopicList
zu einemObservableCollection<T>
die Lösung des aktuellen Problems. Sie könnte füllen Sie auch dieList<T>
vor der Zeit, und dann wird die Bindung über OneWay; jedochObservableCollection<T>
ist ein robuster Ansatz.EDIT:
Ihre
TopicList
werden muss, eine Eigenschaft, die nicht eine member-variable; Bindungen erfordern Eigenschaften. Es tut nicht brauchen, um einDependencyProperty
.EDIT 2:
Ändern Sie Ihre
ItemTemplate
da Sie nicht brauchen, um einHierarchicalDataTemplate
InformationsquelleAutor der Antwort Aaron McIver
Zuerst brauchen Sie nicht eine HeirarchicalDataTemplate. Nur regelmäßige DataTemplate Aaron gegeben hat, ist genug.
Dann müssen Sie instanziieren die TopicList ObservableCollection irgendwo in den Konstruktor der Klasse. das macht die ObservableCollection am Leben, noch bevor Sie Daten hinzufügen, um es Und verbindliches system kennt die Sammlung. Dann, wenn Sie hinzufügen, und jedes Thema/CheckedListItem wird es automatisch zeigt sich in der UI.
InformationsquelleAutor der Antwort Jobi Joy
Andere schon gemacht haben nützliche Vorschläge (verwenden Sie eine observable-collection zu Holen-Liste-change notification, machen die Sammlung zu einer Eigenschaft und nicht als ein Feld). Hier sind zwei, die Sie noch nicht:
1) Wenn du ein problem mit der Datenbindung, Blick in die Ausgabe-Fenster, um sicherzustellen, dass Sie sind nicht immer alle verbindliche Fehler. Sie verbringen eine Menge Zeit, die versucht zu reparieren, das falsche problem, wenn Sie dies nicht tun.
2) Verstehen Sie die Rolle ändern, Benachrichtigung, spielt bei der Bindung. Änderungen in der Datenquelle nicht und kommen die nicht an die Benutzeroberfläche weitergegeben, es sei denn, die Datenquelle implementiert Benachrichtigung ändern. Es gibt zwei Möglichkeiten, dies zu tun für den normalen Eigenschaften: machen Sie die Datenquelle stammen aus
DependencyObject
und machen die gebundene Eigenschaft einer dependency property, oder stellen Sie die Datenquelle implementierenINotifyPropertyChanged
und erhöhen diePropertyChanged
- Ereignis, wenn der Wert der Eigenschaft ändert. Wenn die Bindung einesItemsControl
zu einer Sammlung, eine Sammlung Klasse, dieINotifyCollectionChanged
(wieObservableCollection<T>
), so dass änderungen an den Inhalt und die Reihenfolge der Auflistung bekommen propagiert, um das gebundene Steuerelement. (Beachten Sie, dass wenn Sie möchten, dass änderungen an den Artikeln in die Sammlung zu bekommen propagiert, um die gebundenen Steuerelemente, die Elemente implementieren müssen, um änderungsmitteilung zu.)InformationsquelleAutor der Antwort Robert Rossney
ändern Sie Ihre Bindung an
InformationsquelleAutor der Antwort Binil