c# - WPF ObservableList 调度程序线程

标签 c# .net wpf multithreading dispatcher

我正在将一个项目从 Windows 窗体格式转换为 WPF 格式。目前,我已将所有数据限制在元素中。我现在在 ObservableCollection 中提出一个问题,说:

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

如何使我的代码线程安全?或者我如何引导对 Dispatcher 线程的更改?我看过一些关于它的帖子,但我对如何将它应用到我自己的项目感到困惑。也许有人可以为我阐明这一点?

这是我的ObservableList.cs代码:

public class ObservableList<T> : ObservableCollection<T>
{
    #region Private members

    bool isInAddRange = false;

    #endregion Private members

    #region Public methods

    /// <summary>
    /// Creates a new empty ObservableList of the provided type. 
    /// </summary>
    public ObservableList()
    {

    }

    /// <summary>
    /// Handles the event when a collection has changed.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        // intercept this when it gets called inside the AddRange method.
        if (!isInAddRange)
            base.OnCollectionChanged(e);
    }

    /// <summary>
    /// Adds a collection of items to the ObservableList.
    /// </summary>
    /// <param name="items"></param>
    public void AddRange(IEnumerable<T> items)
    {
        isInAddRange = true;
        foreach (T item in items)
        {
            Add(item);
        }

        isInAddRange = false;

        var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,items.ToList());
        base.OnCollectionChanged(e);

    }

    #endregion Public methods
}

编辑:在 ywm 给出答案后,我将 AddRange 类更改为:

public void AddRange(IEnumerable<T> items)
{
    isInAddRange = true;
    foreach (T item in items)
    {
        if (item != null)
        {
            Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
                {
                    Add(item);
                }));
        }
    }

    isInAddRange = false;

    var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,items.ToList());
    base.OnCollectionChanged(e);

}

现在,我所有的 ObservableList 都是 null

最佳答案

当您将项目添加到 ObservableCollection 时,您需要调用 UI 调度程序线程来执行此操作。

这样做是这样的:

  Dispatcher.CurrentDispatcher.Invoke(() =>
  {
        foreach (var myModel in itemsToAdd)
        {
                    Images.Add(mymodel);                   
        } 
  });

然后在类里面使用它,

    public ObservableList<String> Strings { get; set; }

    public MyViewModel()
    {
        this.Strings = new ObservableList<string>();

        this.Strings.AddRange(new[] { "1", "2", "3", "4" });
    }

关于c# - WPF ObservableList 调度程序线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15022636/

相关文章:

c# - 在浏览器中禁用最近的文本列表

c# - 可以写这样的东西吗?

.net - vb.net:四舍五入到下一个整数

c# - 将用户控件列表插入到特定的列和行

c# - 如何解析 MVC5 中的 wwwroot 路径

c# - 为什么这个 C# 代码返回它所做的

.net - Visual Studio 2008 单元测试 : How to execute one by one?

使用 .net 3.5 进行不带参数的 C# 调用

c# - 在 C#/WPF 中发生特定事件时强制窗口闪烁

c# - 模型需要,但 View 最初为空字段 - MVVM