寻找解释System.NotSupportedException

时间:2015-02-11 07:57:17

标签: c# wpf backgroundworker observablecollection dispatcher

首先是一些代码,最后是问题。 我有一些叫做机器的对象,它们有两个属性

public Logs MachineLogs {
        get { return _logs; }
        set {
            _logs = value;
            NotifyPropertyChanged ("MachineLogs");
        }
    }

    public ObservableCollection<Part> Parts {
        get { return _parts; }
        set {
            _parts = value;
            NotifyPropertyChanged ("Parts");
        }
    }

MachineLogs看起来像这样:

public ObservableCollection<Log> Malfunctions {
        get {
            SortCollection (_malfunctions);
            return _malfunctions;
        }
        set {
            _malfunctions = value;
            NotifyPropertyChanged ("Malfunctions");
        }
    }

    public ObservableCollection<Log> CompletedTasks {
        get {
            SortCollection (_completedTasks);

            return _completedTasks;
        }
        set {
            _completedTasks = value;
            NotifyPropertyChanged ("CompletedTasks");
        }
    }

    public ObservableCollection<LogTemplate> TaskTemplates {
        get { return _taskTemplates; }
        set {
            _taskTemplates = value;
            NotifyPropertyChanged ("TaskTemplates");
        }
    }

现在我在BackgroundWorker中使用序列化克隆Machine,然后将其添加到我存储它的地图中。

protected override void CloneReady ( object sender, RunWorkerCompletedEventArgs e )
    {
        var machine = ((Machine) e.Result);
        _map.Machines.Add (machine);

        var machineControl = new MachineControl (machine, _canvas);
        ((MainWindow) Application.Current.MainWindow).MapPanel.Selector.ProcessSelection (machineControl);

    }

现在问题出在这里。当我向其中添加项目或删除项目时,所有内容都可以正常使用零件集合(两个集合的方法看起来完全相同)。当我尝试对Malfunctions集合执行任何操作时发生异常。

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



private void AddNewEntry(object sender, RoutedEventArgs e) {
        if (LogList.SelectedLog == null)
        {
            var source = (ObservableCollection<Log>) LogList.ItemsSource;

            Log newLog = new Log (LogTypes.Malfunction, ((Machine) DataContext).MachineLogs.Colors.MalfunctionColor.HexValue)
            {
                DbAction = Data.DBSavers.DatabaseActions.Create,
                MachineId = ((Machine) DataContext).Db.Id
            };
            source.Insert (0, newLog);
            LogList.SelectedLog = newLog;
        }
        else
        {
            LogList.SelectedLog = null;
        }
    }

通过UI按钮调用AddNewEntry,尝试调用Dispatcher但仍然没有运气。这种行为有没有解释? 当我使用BackgroundWorker跳过部分时,问题不会发生。我无法跳过它的原因是我需要克隆多台机器(复制/粘贴东西),这可能需要一段时间,所以我不想冻结UI。

protected override void ProduceClone ( object sender, DoWorkEventArgs e )
    {
        var serializer   = new XmlSerializer ();
        var selector     = new MapColorSelector ();
        var machine      = serializer.SerializeMachine (e.Argument as Machine);
        machine.Color    = selector.DefaultColor;
        machine.Location = _location;

        e.Result = machine;
    }

1 个答案:

答案 0 :(得分:0)

我喜欢这个网站如何帮助解决问题。在描述问题并仔细研究之后,大多数答案都来了。 这次是排序方法的错误。去了LINQ,它再次运作,但也许有人可以解释这个:]

private void SortCollection (ObservableCollection<Log> collection) {
        var sorted = CollectionViewSource.GetDefaultView (collection);
        sorted.SortDescriptions.Add (new SortDescription ("Date", ListSortDirection.Ascending));
    }