问题描述
我使用 Messenger 类 在视图模型之间发送数据.有一个 AppView 在内容控件中托管两个主要视图,到目前为止,以这种方式发送/接收数据没有问题.
I'm using a Messenger class in order to send data between view models. There is an AppView that hosts two main views in a content control, and up until now have had no issue with sending/receiving data this way.
问题:
现在我添加了一个 ProductView,它向 AppView 显示一个单独的对话框.但是当我在调用 .ShowDetailDialog() 之后调用 Messenger.Default.Send<ProductModel>(SelectedProduct); 这会阻止 Send 代码调用,直到对话框关闭.
Now I added a ProductView that shows a separate dialog to the AppView. But when I call Messenger.Default.Send<ProductModel>(SelectedProduct); after calling .ShowDetailDialog() this blocks the Send code call, until the dialog is closed.
我尝试了相反的方法,首先调用 Send 代码,然后打开对话框.但这意味着接收 VM 中的消息处理程序在消息发送之前没有及时注册.
I tried the other way around, calling the Send code first, then opening the dialog. But this means that the message handler in the receiving VM doesn't register in time before the message is sent.
有没有人知道解决方案,以防止对话框阻止发送调用?或者在发送消息和显示对话框之前注册 ProductVM 消息处理程序?
Does anyone know of a solution, to prevent the dialog from blocking the send call? Or alternatively register the ProductVM message handler prior to sending message and showing dialog?
以下是相关类的总结:
CustomerOrdersVM(发送代码):
private void EditOrder(object obj)
{
_dialogService.ShowDetailDialog();
Messenger.Default.Send<ProductModel>(SelectedProduct);
}
ProductVM(接收代码):
public ProductViewModel()
{
Messenger.Default.Register<ProductModel>(this, OnSelectedProductReceived);
}
对话服务:
class DialogService : IDialogService
{
Window productView = null;
public DialogService()
{
}
public void ShowDetailDialog()
{
productView = new ProductView();
productView.ShowDialog();
}
}
AppVM(已注册主 VM,ProductVM 独立于该 VM):
public ApplicationViewModel()
{
// Add available pages
PageViewModels.Add(new CustomerDetailsViewModel(customerDataService, countryDataService, dialogService));
PageViewModels.Add(new CustomerOrdersViewModel(orderDataService, dialogService));
PageViewModels.Add(new OrderStatisticsViewModel());
// Set starting page
CurrentPageViewModel = PageViewModels[0];
}
AppView:(保存 AppVM 视图):
<Window x:Class="MongoDBApp.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:MongoDBApp.Views"
xmlns:vm="clr-namespace:MongoDBApp.ViewModels">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:CustomerDetailsViewModel}">
<views:CustomerDetailsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomerOrdersViewModel}">
<views:CustomerOrdersView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:OrderStatisticsViewModel}">
<views:OrderStatisticsView />
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<vm:ApplicationViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".07*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TabControl Grid.Row="1"
ItemsSource="{Binding PageViewModels}"
SelectedItem="{Binding CurrentPageViewModel}"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</Window>
推荐答案
您可以通过以下几种方式解决问题:
You could solve the problem a few ways:
- 不要使用
ShowDialog().使用Show(),使对话窗口 TopMost 并作为主窗口的父窗口. 在DialogService的构造函数中注册
ProductView(真的每次都需要一个新的ProductView吗?)
- Don't use
ShowDialog(). UseShow(), and make the dialog window TopMost and parented to the main window. Register the
ProductViewin the constructor of the DialogService (do you really need a newProductVieweach time anyway?)
使 DialogService(或其中的实用程序类)在构造时为消息注册,然后将消息传递给任何显示的 ProductViews
Make the DialogService (or a utility class inside of it) register at construction time for the message, and then pass the message on to any displayed ProductViews
我个人喜欢 #2- 因为您使用的是 ShowDialog,这意味着一次只需要一个 ProductView.例如:
Personally I like #2- since you are using ShowDialog, it implies that only one ProductView is ever needed at a time. For example:
class DialogService : IDialogService
{
Window productView = null;
ProductView _productView;
public DialogService()
{
_productView = new ProductView();
}
public void ShowDetailDialog()
{
_productView.ShowDialog();
}
}
这篇关于如何在 ShowDialog() 阻塞调用之前注册消息处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!


大气响应式网络建站服务公司织梦模板
高端大气html5设计公司网站源码
织梦dede网页模板下载素材销售下载站平台(带会员中心带筛选)
财税代理公司注册代理记账网站织梦模板(带手机端)
成人高考自考在职研究生教育机构网站源码(带手机端)
高端HTML5响应式企业集团通用类网站织梦模板(自适应手机端)