从类创建ObservableCollection

时间:2012-10-18 10:27:01

标签: c# wpf observablecollection

我有一个带有事件日志的WPF应用程序。我有一个EventLog类,我在应用程序启动时填充了XML文件中保存的事件

namespace MyApp.Agent.EventLogging
{
    public enum EventType
    {
        Infomation,
        Error
    }
    public class EventLog
    {
        public String Image { get; set; }
        public DateTime EventDate { get; set; }
        public String EventText { get; set; }
    }
}

public List<EventLog> GetSavedEvents()
{
   string file = XmlUtilities.GetXmlLocation() + "\\Events.xml";
   List<EventLog> elog = new List<EventLog>();
   try
   {
       if (File.Exists(file))
       {
          Serialize<List<EventLog>> ser = new Serialize<List<EventLog>>();
          elog = ser.DeserializeDocToObj(file);
       }
   }
   catch
   {
          throw new InvalidEventLogException(ConfigurationManager.AppSettings.Get("EventLogFileInvalid"));
   }
 return elog;
}

然后我将其转换为listview绑定的可观察集合

List<EventLog> _evtLog = new List<EventLog>();
ObservableCollection<EventLog> _eventLog = new ObservableCollection<EventLog>();
_evtLog = logger.GetSavedEvents();
_evtLog.ForEach(x => _eventLog.Add(x));

我读到这就是必须要做的事情(尽管看起来似乎是漫长的方式)

当应用程序运行时,新事件将添加到可观察集合中。当应用程序关闭时,我会反转此过程以保存事件。

虽然只有少数保存的事件可以正常工作,因为列表越来越大所以这样做的时间变得不切实际(240K事件需要7秒)。好的第一个问题,你可能会问,为什么我会想要那么多事件,事实是我没有,但它确实强调我不是这样做的最佳方式?

所以我的问题是:

我真的需要填充可观察的集合吗?如果没有填充另一个,我可以不_evtLog可观察吗?

我可以根据活动日期将这些列表限制为X事件吗?

3 个答案:

答案 0 :(得分:2)

您可以轻松更改GetSavedEvents以序列化和反序列化ObservableCollection<EventLog>而不是List<EventLog>

话虽如此,将列表转换为可观察集合的代码看起来很奇怪。你为什么不只是使用适当的构造函数?

_eventLog = new ObservableCollection<EventLog>(logger.GetSavedEvents());

使用Add的问题在于,对于要添加的每个项目,您都会举起一个事件。

答案 1 :(得分:2)

以下将创建ObservableCollection

var _eventLog = new ObservableCollection<EventLog>(logger.GetSavedEvents());

关于过滤结果,是的,您可以快速LINQ选择查询来定义限制,并将结果作为List传递给ObservableCollection

关于过滤结果的一些想法

根据您的需要,您可能需要进行一些调整

var _eventLog = new ObservableCollection<EventLog>(logger.GetSavedEvents().where(event => event.date == some date).ToList());

答案 2 :(得分:0)

这是生成ObservableCollection的实际代码吗?从240k元素列表生成OC不应该花费7秒,它应该几乎是瞬时的。

您确定没有将事件添加到已绑定到列表视图的集合中,导致列表视图针对每个项目进行更新吗?

尝试使用此而不是ObservableCollection:

class MyObservableCollection<T> : ObservableCollection<T>
{
    private bool _notifyCollectionChanged = true;

    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (_notifyCollectionChanged)
            base.OnCollectionChanged(e);
    }

    public void AddRange(IEnumerable<T> collection)
    {
        _notifyCollectionChanged = false;
        foreach (T element in collection)
            Add(element);
        _notifyCollectionChanged = true;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}

使用oc.AddRange(list)将List添加到ObservableCollection。

如果这没有帮助,那么你的GetSavedEvents函数可能正在运行7秒,它与ObservableCollection无关。