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