我已经与WPF
和ObservableCollection
进行了很长时间的斗争,现在我需要一些帮助。
这是设置和要求
ObservableCollection
所以基本上这是一个滚动日志视图,其中一个条目进入,一个条目退出。我必须保持所选项目并实时显示更新(这就是我使用ObservableCollection
的原因)。可以过滤日志并导航页面,因此我认为当有新的日志条目并显示时,最简单的方法是获取整个页面;这也可以让我获得以前可能错过的条目。
我对此有很多问题,包括在后台线程上更新集合的问题,最近的问题是DataGrid
"闪烁"何时创建新条目。我假设闪烁是每次刷新整个集合引起的,但替代方案(手动添加和删除项目)要复杂得多,而且由于过滤的复杂性,我不愿意去那条路线和传呼。
是否有任何良好的模式或建议可以阻止这种情况和#34;闪烁"或者更好的方法来实现可实时更新的可过滤日志视图?
的Xaml
<DataGrid ItemsSource="{Binding Entries, IsAsync=True}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserSortColumns="False"
EnableColumnVirtualization="True" EnableRowVirtualization="True"
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
<DataGrid.Columns>
<DataGridTextColumn Header="Timestamp" Binding="{Binding Timestamp}" />
<DataGridTextColumn Header="From" Binding="{Binding MessageFrom}" />
<DataGridTextColumn Header="To" Binding="{Binding MessageTo}" />
<DataGridTextColumn Header="Type" Binding="{Binding MessageType}" />
</DataGrid.Columns>
</DataGrid>
我使用的绑定的ViewModel代码
//option 1
public ViewModel() { this.Entries = new ObservableCollection<Model>(); }
public void UpdateData()
{
this.Entries.Clear();
foreach (Model m in FetchModels())
this.Entries.Add(m);
}
public ObversableCollection<Model> Entries { get; private set; }
//option 2
private List<Model> m_Entries = new List<Model>();
public void UpdateData()
{
this.m_Entries.Clear();
this.m_Entries.AddRange(FetchModels());
this.NotifyPropertyChanged(() => this.Entries);
}
public ObversableCollection<Model> Entries { get { return new ObservableCollection<Model>(this.m_Entries); } }
//option 3
public ViewModel() { this.Entries = new ObservableCollection<Model>(); }
public void UpdateData()
{
var tmp = this.Entries;
this.Entries = null;
tmp.Clear();
foreach (Model m in FetchModels())
tmp.Add(m);
this.Entries = tmp;
this.NotifyPropertyChanged(() => this.Entries);
}
public ObversableCollection<Model> Entries { get; private set; }
一旦我记得我尝试过的更多内容,我就会发布它。
答案 0 :(得分:0)
这是我想出来的,似乎工作得很好,虽然我不喜欢它,并认为我可能会倾向于上述评论中的Lee O建议;但与此同时,由于截止日期临近,这就是我所做的。 UpdateData
是它自己的主题。
public void UpdateData()
{
var items = this.m_Cache.All<Model>().OrderByDescending(x => x.Timestamp).Take(50).Skip(0).ToList();
lock (this.m_Sync)
{
var toRemove = this.Entries.Except(items).ToList();
var toAdd = items.Except(this.Entries).ToList();
foreach (Model m in toAdd)
this.Entries.Add(m);
foreach (Model m in toRemove)
this.Entries.Remove(m);
}
this.NotifyOfPropertyChange(() => this.TotalRecords);
}