wpf 使用NServiceBus时,MVVM中的ObservableCollection未发生变化

gab6jxml  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(125)

我在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(..); Task.Wait();添加对象,假设它可能需要一些时间。它没有帮助。
请告诉我如何解决这个问题,为什么会发生?

bttbmeg0

bttbmeg01#

好了,这里的问题是NServiceBus将创建一个ViewModel的新示例来处理消息,这显然不是您想要的。
相反,ViewModel和消息Handler应该是独立的对象,然后处理程序可以告诉ViewModel关于消息的信息。
我不确定您使用的是什么MVVM框架,但通常有某种事件聚合器用于从系统组件(如NServiceBus处理程序和ViewModel)传递消息。

roejwanj

roejwanj2#

确保使用dispatcher在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;
    }
}

相关问题