Veränderungen in der ObservableCollection nicht aktualisieren ListView
Habe ich gewesen das Lesen der entsprechenden Artikel hier im board, aber ich kann immer noch nicht mein problem lösen, dass ich beim binden eine ObservableCollection in eine ListView.
Ich habe eine CLogEntry model-Klasse, die im Grunde wickelt eine Schnur.
///Model of LogEntry
public class CLogEntry:INotifyPropertyChanged
{
///Fields
private string _logEntry;
///Property
public string LogEntry
{
get { return _logEntry; }
set
{
_logEntry = value;
RaisePropertyChanged("LogEntry");
}
}
///PropertyChanged event handler
public event PropertyChangedEventHandler PropertyChanged;
///Constructor
public CLogEntry(string logEntry)
{
this.LogEntry = logEntry;
}
///Property changed Notification
public void RaisePropertyChanged(string propertyName)
{
//take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
In meinem ViewModel-ich habe eine ObservableCollection, dass hält meine CLogEntry Objekte sowie die entsprechenden öffentlichen Eigentum.
class CLoggerViewModel : INotifyPropertyChanged
{
///Memory Appender object
private CMemoryAppender _memoryAppender;
///ObservableCollection for LogEntries
private ObservableCollection<CLogEntry> _logEntries;
///Property to expose ObservableCollection for UI
public ObservableCollection<CLogEntry> LogEntries
{
get { return _logEntries; }
}
///Event for PropertyChanged Notification
public event PropertyChangedEventHandler PropertyChanged;
///Constructor of viewModel
public CLoggerViewModel()
{
this._logEntries = new ObservableCollection<CLogEntry>();
this._memoryAppender = new CMemoryAppender();
this._memoryAppender.PropertyChanged += new PropertyChangedEventHandler(OnMemoryAppenderPropertyChanged);
this._memoryAppender.LogContentChanged += new LoggingEventHandler(OnLogContentChanged);
}
///Update collection
public void OnLogContentChanged(object sender, LoggingEventArgs e)
{
/// Here i add LogEntries event based to my collection.
/// For simplicity i just used a temporarly string here.
string[] tmpString = { "A", "B", "C", "D" };
foreach (string s in tmpString)
{
this.LogEntries.Add(new CLogEntry(s));
}
}
///Any of the properties of the MemoryAppender objects has changed
private void OnMemoryAppenderPropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.RaisePropertyChanged(e.PropertyName);
}
///PropertyChanged EventHandler
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Meiner XAML-code für das ListView-Steuerelement die folgenden:
<ListView x:Name="lstLogs" DataContext ="{Binding LoggerViewModel}" ItemsSource="{Binding LogEntries}" Margin="5,5,5,5" Grid.Column="1" Grid.Row="0">
<ListView.View>
<GridView x:Name="grdLogs">
<GridViewColumn Header="Log Entry" DisplayMemberBinding="{Binding Path=LogEntries}"/>
</GridView>
</ListView.View>
</ListView>
Mein Problem ist, dass die Liste zeigt keine Daten.
Aber wenn ich Debuggen Sie den code, den ich kann sehen, dass mein Grundstück für die ObservableCollection aufgerufen wird und, dass meine Sammlung enthält alle Logeinträge, die ich hinzufügen.
Also gehe ich davon aus, dass das CollectionChanged-Ereignis gefeuert wird und das UI ist Sie meine Logeinträge Eigenschaft.
Aber ich verstehe nicht, warum das ListView-Steuerelement zeigt nicht alle Daten.
Gibt es ein problem mit meinem XAML code oder ist es ein problem im Modell-und/oder ViewModel?
EDIT:
Schließlich das problem war ein threading-Problem.
Da die ObervableCollection erstellt wird, von der UI-thread erzeugt eine Ausnahme, wenn ein anderer thread hinzufügen/Bearbeiten die Sammlung.
Um loszuwerden dieses problem, das ich die folgende Lösung gefunden, die eine Asynchrone ObservableCollection.
Folgenden links, die mir geholfen es zum laufen zu bringen:
Stackoverflow
Implementierung Von Async-ObservableCollection
DataContext
? Und wenn Sie instanziieren LogEntries
Eigenschaft?pls verwenden Sie Snoop zur überprüfung Ihrer DataContext-und Binding-Ausdrucks zur Laufzeit
Spoof ist mir zu sagen: DataContext - [Logger.CLoggerViewModel] {Pfad=LoggerViewModel}. Aber für die BindingExpression im nicht sicher. ich fand gerade die Eigenschaften für die Bindung.XmlNamespaceManager-und BindingGroup für das ListView in der Parodie. Aber beide Eigenschaften dont halten Sie einen beliebigen Wert während der Laufzeit.
InformationsquelleAutor ck84vi | 2014-09-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
wenn die DataContext ist dein viewmodel (CLoggerViewModel), dann wird die Itemssource-Bindung sollte sein:
und der verbindliche Ausdruck Ihrer LogEntry sollte einfach sein {Binding LogEntry}
EDIT:
EDIT: zu deinem neuesten updates
DataContext ="{Binding LoggerViewModel}" --> Was ist das? dies bedeutet, dass Sie eine öffentliche Eigenschaft mit dem Namen LoggerViewModel auf Ihrem aktuellen Datacontext. ich glaube nicht, dass es das ist, was Sie wollen. der Viewmodel-code sieht ok, aber das problem ist der XAML-und Einstellung Datacontext. also pls poste den code, wo Sie die DataContext.
EDIT: funktioniert code
cs
die ItemsSource-Bindung sollte Logeinträge und nicht LoggerViewModel.
Das ist, was ich habe -> " ItemsSource="{Binding Logeinträge}" . Ich habe aktualisiert, dies vorher in meinem post. Wie ich schon sagte. Da habe ich meine foreach-Schleife Stoppt hinzufügen von Objekten zu der Auflistung nach dem hinzufügen des ersten Objekts.
haben Sie diese in Ihrem ctor: _logEntries = new ObservableCollection<CLogEntry>(); ? mein test-Projekt arbeitet mit Ihrem code. btw ich hatte einen kleinen Fehler in DisplayMemberBinding. siehe mein update
Ja, instanziiere ich es im Konstruktor. Ich update meinen post entsprechend. Aber wenn ich Ihren XAML-es funktioniert nicht. Was ich gefunden habe ist, dass wenn ich
DisplayMemberBinding="{Binding Path=LogEntry}"
IntelliSense nicht bieten mir die Eigenschaft LogEntry. Ich bekomme nur Logeinträge, die von meiner VM. Also ich kann nur binden Sie die gesamte Sammlung nicht die LogEntry-Eigenschaft selbst. Könnte es sein, dass ich irgendein problem in meinem ViewModel oder Model?InformationsquelleAutor blindmeis