我正在使用Messenger class来在视图模型之间发送数据。有一个AppView
在内容控件中托管两个主要视图,到目前为止,这种方式发送/接收数据没有任何问题。
问题:
现在我添加了一个ProductView
,它显示了一个单独的AppView对话框。但是当我在调用.ShowDetailDialog()之后调用Messenger.Default.Send<ProductModel>(SelectedProduct);
时,会阻止Send
代码调用,直到对话框关闭。
我尝试了另一种方法,首先调用Send
代码,然后打开对话框。但这意味着接收VM中的消息处理程序在发送消息之前不会及时注册。
是否有人知道解决方案,以防止对话框阻止发送呼叫?或者在发送消息和显示对话框之前注册ProductVM消息处理程序?
以下是相关课程的摘要:
CustomerOrdersVM(发送代码):
private void EditOrder(object obj)
{
_dialogService.ShowDetailDialog();
Messenger.Default.Send<ProductModel>(SelectedProduct);
}
ProductVM(接收代码):
public ProductViewModel()
{
Messenger.Default.Register<ProductModel>(this, OnSelectedProductReceived);
}
DialogService:
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>
答案 0 :(得分:2)
您可以通过以下几种方式解决问题:
ShowDialog()
。使用Show()
,并将对话窗口设为TopMost,并将其作为主窗口的父级。在DialogService的构造函数中注册ProductView
(每次你真的需要一个新的ProductView
吗?)
使DialogService
(或其中的实用程序类)在构造时注册消息,然后将消息传递给任何显示的ProductView
我个人喜欢#2-因为你使用ShowDialog
,这意味着一次只需要一个ProductView
。例如:
class DialogService : IDialogService
{
Window productView = null;
ProductView _productView;
public DialogService()
{
_productView = new ProductView();
}
public void ShowDetailDialog()
{
_productView.ShowDialog();
}
}