我已经阅读了论坛中所有相关文章,但在将ObservableCollection绑定到ListView时仍然无法解决我的问题。
我有一个CLogEntry模型类,基本上包装了一个字符串。
在我的ViewModel中,我有一个ObservableCollection,它保存了我的CLogEntry对象以及相应的公共属性。
我的问题是列表没有显示任何数据。 但是当我调试代码时,我可以看到我的ObservableCollection属性被调用,我的集合保存了我添加的所有LogEntries。 因此,我假设CollectionChanged事件被触发并且UI正在调用我的LogEntries属性。 但我不明白为什么ListView没有显示任何数据。
我的XAML代码有问题还是模型和/或ViewModel有问题?
编辑:
最终问题是一个线程问题。 由于ObervableCollection是由UI线程创建的,如果另一个线程正在添加/操作集合,则会抛出异常。 为了解决这个问题,我找到了以下解决方案,实现了一个异步ObservableCollection。
以下链接帮助我让它工作: Stackoverflow Implementing Async ObservableCollection
我有一个CLogEntry模型类,基本上包装了一个字符串。
/// 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));
}
}
}
在我的ViewModel中,我有一个ObservableCollection,它保存了我的CLogEntry对象以及相应的公共属性。
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));
}
}
}
我的ListView的XAML代码如下:
<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>
我的问题是列表没有显示任何数据。 但是当我调试代码时,我可以看到我的ObservableCollection属性被调用,我的集合保存了我添加的所有LogEntries。 因此,我假设CollectionChanged事件被触发并且UI正在调用我的LogEntries属性。 但我不明白为什么ListView没有显示任何数据。
我的XAML代码有问题还是模型和/或ViewModel有问题?
编辑:
最终问题是一个线程问题。 由于ObervableCollection是由UI线程创建的,如果另一个线程正在添加/操作集合,则会抛出异常。 为了解决这个问题,我找到了以下解决方案,实现了一个异步ObservableCollection。
以下链接帮助我让它工作: Stackoverflow Implementing Async ObservableCollection
DataContext
?并且在何时实例化LogEntries
属性? - har07