【问题标题】:Slow Down Refresh Rate Of Bound DataGrid降低绑定DataGrid的刷新率
【发布时间】:2011-05-25 20:04:39
【问题描述】:

我的 WPF/C# 应用程序中有一个绑定到实体框架集合的 DataGrid。每行都有非常频繁地更改的绑定列 - 每秒多次。这导致该列基本上不可读,因为它经常更改。如何强制 WPF 每 0.5 秒或 1 秒仅显示一个新值,即使该值每 0.1 秒更改一次?

例如

dataGrid.MaxRefreshRate = 1000; (value in milliseconds).

【问题讨论】:

  • 由于这个问题被标记为 WPF,我假设您的意思是 DataGrid? DataGridView 是 Windows 窗体。另外,Columns 或 Collection 是否会快速变化?
  • @Meleak - 是的,对不起,我的意思是 WPF 中的 DataGrid。集合更改很快,这反过来意味着 DataGrid 从 INotifyPropertyChanged 事件更新得太频繁。我只想让 DataGrid 基本上忽略一些属性更改事件,而只更新,比如说,每秒一次。
  • 不允许用户更新数据网格中的数据吗?要确认其他同步问题,需要通过此延迟更新来解决。
  • @bjoshi - 实际上,我不需要启用 TwoWay,只需要从 DataSource 到 DataGrid 的 OneWay。希望这可以简化它。

标签: c# wpf data-binding datagrid refresh


【解决方案1】:

我认为您需要在数据和数据网格之间创建一个层。

假设您的数据是 List 类型,并且目前它已绑定到您的 DataGrid。

我们需要一些包装类来存储您的数据(在本例中为一行)。此包装器延迟更改属性并定期触发它。注意:我在没有任何测试的情况下用心编写了这段代码,可能(并且将会)存在错误。它也不是线程安全的,在使用列表时需要添加一些锁。但应该抓住重点。

public class LazyRecord : INotifyPropertyChanged
{
  private string name;
  public string Name
  {
    get { return name; }
    set
    {
      if (name != value)
      {
         name = value;
         OnPropertyChanged("Name");
      }
    }

    // other properties

    // now the important stuff - deffering the update
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
       if (this.changedProperties.Find(propertyName) == null)
        this.changedProperties.Add(propertyName);
    }

    private readonly List<string> changedProperties = new List<string>();

    // and the timer that refreshes the data
    private readonly Timer timer;
    private readonly Record record;

    public LazyRecord(Record record)
    {
       this.timer = new Timer(1000, OnTimer);
       this.record = record;

       this.record.OnPropertyChanged += (o, a) => this.OnPropertyChanged(a.PropertyName);
    }

    public void OnTimer(..some unused args...)
    {
       if (this.PropertyChanged != null)
       {
        foreach(string propNAme in changedProperties)
        {
           PropertyChanged(new PropertyChangedEventArgs(propName));
        }
    }
}

在此之后,只需从您的 List 创建一个 List 并将其用作您的数据源。显然,使用通用解决方案很简单,它的可重用性要高得多。希望我能帮上一点忙。

【讨论】:

  • 感谢您的示例和注释。我认为这会很好。
【解决方案2】:

只是一个想法,它是如何工作的。

  • 将数据的卷影副本绑定到 gui 元素,而不是绑定原始数据。
  • 添加一个事件处理程序,用于更新卷影副本,并在原始数据中产生一定的延迟。

也许你会在类似的新问题how-to-do-the-processing-and-keep-gui-refreshed-using-databinding找到更多更好的答案

【讨论】:

  • 感谢您的想法和链接。链接上的一个答案似乎足够有用且足够通用,可以重复使用。当然,这似乎仍然是一个很常见的问题,我希望 DataGrid 中内置一些东西。
【解决方案3】:

试试listView.Items.Refresh();

【讨论】:

  • 好吧,我不想强​​制刷新。事实上,如果它们离上次刷新太近,我想取消一些刷新。我确实找到了 dataGridView.Items.DeferRefresh() 但我不确定如何使用它,或者它是否是正确的方法。我在尝试: using(dataGridView.Items.DeferRefresh()) { Thread.Sleep(500); }
猜你喜欢
  • 2011-06-27
  • 2013-03-18
  • 2012-07-05
  • 2014-10-30
  • 2014-03-06
  • 2021-10-20
  • 2014-02-01
  • 2019-11-20
  • 2012-06-24
相关资源
最近更新 更多