WPF MVVM更新集合,以便UI更新

WPF MVVM更新集合,以便UI更新,wpf,mvvm,backgroundworker,observablecollection,Wpf,Mvvm,Backgroundworker,Observablecollection,我想更新我的用户界面。我应该使用BackgroundWorker吗?我是将BackgroundWorker放入MainWindowViewModel并再次实例化存储库,还是将其放入OrdersQueueViewModel并对属性进行处理 UI只显示LINQ创建的列表的内容。这些列表是ObservableCollection,是OrdersQueueViewModel的属性。我有一个ViewModel MainWindowViewModel,它创建了一个集合ViewModels,这样我就可以从Ma

我想更新我的用户界面。我应该使用BackgroundWorker吗?我是将BackgroundWorker放入MainWindowViewModel并再次实例化存储库,还是将其放入OrdersQueueViewModel并对属性进行处理

UI只显示LINQ创建的列表的内容。这些列表是ObservableCollection,是OrdersQueueViewModel的属性。我有一个ViewModel MainWindowViewModel,它创建了一个集合ViewModels,这样我就可以从MainWindow.xaml视图绑定到该集合

MainWindowViewModel.cs:

public MainWindowViewModel()
{
    _printQueueRepos = new OrdersPrintQueueRepository();
    _holdQueueRepos = new OrdersHoldQueueRepository();            
    _linesToPickRepos = new LinesToPickRepository();
    _linesPerHourRepos = new LinesPerHourRepository();

    //create an instance of viewmodel and add it to the collection            
    OrdersQueueViewModel viewModel = new OrdersQueueViewModel(_printQueueRepos, _holdQueueRepos, _linesToPickRepos, _linesPerHourRepos);
    this.ViewModels.Add(viewModel);              
}
MainWindow.xaml:

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:OrdersQueueViewModel}">
        <vw:OrdersQueueView></vw:OrdersQueueView>
    </DataTemplate>
</Window.Resources>

您可以通过任何一种方式执行此操作-在MainWindowViewModel中或在其中一个子视图模型中。我会根据哪种方式在组件之间产生低耦合和高内聚来选择。更低的耦合-更少的依赖性。更高的内聚性——在逻辑上属于同一类的事物在一起

而BackgroundWorker是一种合理的技术。只需记住分派到UI线程以更新集合。至于你的可观测收集代码。。。这需要一些工作。不要重新验证可观察到的收集。这样做:

public ObservableCollection<LinesToPick> LinesToPick { get; private set; }  // Don't forget to nstantiate in ctor

public void Refresh()
{
    LinesToPick.Clear();
    foreach(var item in _linesToPickRepos.GetLinesToPick())
    {
        LinesToPick.Add(item);
    }
}

通过保持与数据绑定相同的ObservableCollection,您的UI将自动获取对集合的更改。如果替换该集合,则会丢失与该集合的绑定,并且在通知它包含该集合的属性已更改之前,UI不会更新。只保留同一个集合要容易得多。

我原来的问题得到了回答,我并不真的想开始一个新的线程,希望你也知道,你可以为我指出这个新部件的正确方向。你的Dispatcher代码是完全正确的。您希望从BackgroundWorker内部调用调度程序,而不是相反。顺便说一句,我的刷新代码有点幼稚。您应该在后台线程上获取新项目的列表,并将其传递到RefreshnewItems中,而不是从Refresh中调用repo。
Action workAction = delegate
{
    _worker = new BackgroundWorker();
    _worker.DoWork += delegate
    {
        LinesThroughput.Clear();
        LinesToPick.Clear();

        //refresh LinesToPick
        foreach (var item in _linesToPickRepos.GetLinesToPick())
        {
            LinesToPick.Add(item);
        }

       //refresh LinesThroughput
       List<LinesThroughput> Lines = new List<LinesThroughput>    (_linesPerHourRepos.GetLinesThroughput());

       foreach (var item in GetLinesThroughput(Lines))
       {
           LinesThroughput.Add(item);
       }
   };
   _worker.RunWorkerAsync();
};
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, workAction);
public ObservableCollection<LinesToPick> LinesToPick { get; private set; }  // Don't forget to nstantiate in ctor

public void Refresh()
{
    LinesToPick.Clear();
    foreach(var item in _linesToPickRepos.GetLinesToPick())
    {
        LinesToPick.Add(item);
    }
}