使用 NServiceBus 时,MVVM 中的 ObservableCollection 没有改变

问题描述 投票:0回答:2

我的 MVVM 应用程序中的 ObservableCollection 有一个奇怪的行为,更确切地说,是在负责从 NServiceBus 接收消息的代码部分:

public class MyViewModel: ViewModelBase, IHandleMessages<CarMoved>
{
 public ObservableCollection<CarData> Cars= new ObservableCollection<CarData>();


 public Task Handle(CarMoved message, IMessageHandlerContext context)
 {
   ...
   Cars.Add(new Car());

   return Task.CompletedTask;
 }

}

所以我希望 Handle 方法将一个新对象添加到我的 ObservableCollection 中,但对象的数量保持不变。 我创建了测试按钮来检查是否可以使用按钮添加新对象,并且该测试按钮工作正常。 我还调试了 Handle 方法,我可以看到当我在 Handle 方法中时,Observable 集合中的对象数量增加了,但是一旦我离开该方法,所有这些都发生了变化 - 对象的数量返回到旧的数量.

我尝试使用 Task.Run(..); 添加对象任务.Wait();假设也许需要一些时间。这没有帮助。

请告知我如何解决此问题以及为什么会发生?

c# wpf mvvm messaging nservicebus
2个回答
4
投票

好的,所以这里的问题是 NServiceBus 将创建 ViewModel 的新实例来处理消息。这显然不是你想要的。

相反,

ViewModel
和消息
Handler
应该是单独的对象。然后处理程序可以告诉
ViewModel
该消息。

我不确定您使用的是什么 MVVM 框架,但通常有某种事件聚合器用于从 NServiceBus 处理程序和 ViewModel 等系统组件传递消息。


0
投票

确保您使用调度程序访问 UI 线程上的

ObservableCollection

public Task Handle(CarMoved message, IMessageHandlerContext context)
{
    Application.Current.Dispatcher.BeginInvoke(new Action(() => { Cars.Add(new Car()); }));

    return Task.CompletedTask;
}

或者,您可以尝试使用 BindingOperations.EnableCollectionSynchronization 方法来启用跨多个线程访问集合:

public class MyViewModel : ViewModelBase, IHandleMessages<CarMoved>
{
    private readonly object _lock = new object();
    public ObservableCollection<CarData> Cars = new ObservableCollection<CarData>();

    public MyViewModel()
    {
        Application.Current.Dispatcher.Invoke(() => BindingOperations.EnableCollectionSynchronization(Cars, _lock));
    }

    public Task Handle(CarMoved message, IMessageHandlerContext context)
    {
        Cars.Add(new Car());
        return Task.CompletedTask;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.