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

时间:2015-12-18 01:15:24

标签: c# wpf dialog messaging message-listener

我正在使用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>

1 个答案:

答案 0 :(得分:2)

您可以通过以下几种方式解决问题:

  1. 不要使用ShowDialog()。使用Show(),并将对话窗口设为TopMost,并将其作为主窗口的父级。
  2. 在DialogService的构造函数中注册ProductView(每次你真的需要一个新的ProductView吗?)

  3. 使DialogService(或其中的实用程序类)在构造时注册消息,然后将消息传递给任何显示的ProductView

    < / LI>

    我个人喜欢#2-因为你使用ShowDialog,这意味着一次只需要一个ProductView。例如:

    class DialogService : IDialogService
    {
        Window productView = null;
        ProductView _productView;
    
        public DialogService()
        {
             _productView = new ProductView();
        }
    
        public void ShowDetailDialog()
        {
            _productView.ShowDialog();
        }
    }