【问题标题】:Optimize assigning data to ObservableCollection优化分配数据到 ObservableCollection
【发布时间】:2013-11-15 02:59:29
【问题描述】:

我有一个 ObservableCollection 填充代表日历的列表框。

private ObservableCollection<DateItem> _DateList = new ObservableCollection<DateItem>();
public ObservableCollection<DateItem> DateList { get { return _DateList; } }

当用户请求下个月时,我从一个单独的类中获取已经解析的月份,并将它们分配给我的 ObservableCollection,如下所示:

// clear DateList first
DateList.Clear();
// set month
foreach (DateItem item in parsemonth.GetNextMonth())
    Dispatcher.BeginInvoke(() => DateList.Add(item));

一切正常。但是清除数据并添加新数据在视图中几乎需要一秒钟的时间。我想知道这是否可以优化,以便我可以减少日历不显示数据的时间。

编辑:这只发生在实际设备(Lumia 920)上,在模拟器上没有这样的延迟。

【问题讨论】:

    标签: c# windows-phone


    【解决方案1】:

    如果您的集合很大,问题可能在于您要为每个添加的项目发送一个事件。由于您总是清除集合,您可以创建一个 ObservableCollection 版本,在添加项目时禁用更新:

    /// <summary>
    /// An observable collection that supports batch changes without sending CollectionChanged
    /// notifications for each individual modification
    /// </summary>
    public class ObservableCollectionEx<T> : ObservableCollection<T>
    {
        /// <summary>
        /// While true, CollectionChanged notifications will not be sent.
        /// When set to false, a NotifyCollectionChangedAction.Reset will be sent.
        /// </summary>
        public bool IsBatchModeActive
        {
            get { return _isBatchModeActive; }
            set
            {
                _isBatchModeActive = value;
    
                if (_isBatchModeActive == false)
                {
                    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                }
            }
        }
        private bool _isBatchModeActive;
    
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (!IsBatchModeActive)
            {
                base.OnCollectionChanged(e);
            }
        }
    }
    

    用法:

    DateList.IsBatchModeActive = true;  // Disables collection change events
    DateList.Clear();
    
    foreach (DateItem item in parsemonth.GetNextMonth())
        DateList.Add(item);
    
    DateList.IsBatchModeActive = false;  // Sends a collection changed event of Reset and re-enables collection changed events
    

    【讨论】:

    • 有趣!我可以在添加所有项目后手动发送 CollectionChanged 事件,以便更新视图吗?
    • 当您将 IsBatchModeActive 设置为 false 时,将发送 collectionchanged 事件。我将在我的答案中添加一个用法部分。
    • 似乎快了一点,不多但仍然。谢谢!
    • Mm 多测试了一下,看来这只适用于模拟器。在设备上,即使 DateList.IsBatchModeActive 一直为真,视图仍会更新...
    • 您还在调度 Add 调用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 2018-08-22
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多