c# – 如何在ShowDialog()阻塞调用之前注册消息处理程序?

我正在使用
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();
    }
}
点赞