【问题标题】:wpf mvvm binding List<int> to Listbox from background threadwpf mvvm 将 List<int> 从后台线程绑定到 Listbox
【发布时间】:2011-05-12 19:26:55
【问题描述】:

我对 wpf 和 mvvm 很陌生,所以这可能是一个简单的问题,但我希望有人可以向我解释。我的模型中有一个类,它所做的只是轮询进程,如果它看到“calc”正在运行,它会将它的进程 ID 添加到列表中。如果您关闭 calc.exe,它会将其从列表中删除。如果列表发生变化,它会触发并发生事件。在我的 ViewModel 中,我订阅了该事件并更新了触发 PropertyChanged 的​​属性。现在,如果我的属性是视图模型中的列表,那么我的视图中的绑定不会正确更新。如果我将我的列表更改为模型和视图模型中的 ObservableCollection,那么我会遇到跨线程问题。但是,如果我将列表留在模型中并将 ViewModel 中的属性更改为 ObservableCollection 并将列表的值复制到可观察集合中,一切都会按预期工作......我不明白,我真的需要进行复制以使我的 ListBox 中的绑定正常工作吗?

【问题讨论】:

    标签: wpf multithreading mvvm listbox


    【解决方案1】:

    看看 Cinch 实现的 DispatcherNotifiedObservableCollection。如果需要,它将自动使用 Dispatcher。阅读这篇文章以查看它的代码:

    http://www.codeproject.com/KB/WPF/CinchIII.aspx#ObsCol

    【讨论】:

      【解决方案2】:

      您需要从调度线程更新可观察集合。

      类似的东西(在技术上/语法上不正确,但伪接近)

      Dispatcher.BeginInvoke( () => theList.Add( theThing ) );
      

      【讨论】:

      • 我不确定我是否完全遵循这一点。 Dispatcher 在我看来不是我的 viewModel。在 MVVM 中,我的 ViewModel 不应该独立于我的 UI 吗?
      • 是的,可能。但是... UI 所依赖的集合更改通知必须来自调度线程。
      【解决方案3】:

      实现此功能的更好方法是通过 ViewModel 中的属性公开模型,并将 ListBox 绑定到 Model.ObservableList。并在向此列表添加和删除项目时使用 John 的建议。这不需要您将列表中的值复制到 observablecollection。

      所以你的 viewModel 代码会喜欢

          public class ViewModel
          { 
              public Model Model { get { return _model; } }
          }
      

      xaml 中的绑定:

          <ListBox ItemsSource=Model.ObservableList/>
      

      其中 ObservableList 属性返回您的 ObservableCollection。

      由于 WPF 中的所有 UI 元素都具有线程关联(与 Dispatcher 线程相关),因此对 UI 的任何更新都应通过 Dispatcher 进行封送处理。您可以使用 Dispatcher.Invoke 通过 Dispatcher 编组调用。在这种情况下,您的视图、viewModel 和 Model 驻留在 Dispatcher 线程中,因此任何通过 viewModel 或 Model 更新 UI 的调用都需要您调用 Dispatcher.Invoke。

      【讨论】:

      • 我不会说它有必要更好——因为现在你的 ViewModel 暴露的比它需要的要多得多。任何与之交互的东西现在都可以访问模型中的所有东西。
      • 没错,但是在 MVVM 中,由于 Views 和 ViewModels 具有一对一的关系,我认为这是一个可以接受的风险(我猜什么可以接受,什么不可以取决于你的用例)。当我使用这种模式时,我会确保模型的设计只公开相关的属性。
      • 为什么在 MVVM 中视图和视图模型之间需要一对一的关系?没有什么能阻止您重用。我可以看到很多可以将视图模型用于不同视图的用例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2014-08-02
      • 2011-05-09
      相关资源
      最近更新 更多