How to register a message handler before calling ShowDialog ()?

I use the Messenger class to send data between view models. There is AppView, which contains two main types in the content control and so far has not had problems sending / receiving data in this way.

Question:

Now I have added ProductView, which shows a separate AppView dialog. But when I Messenger.Default.Send<ProductModel>(SelectedProduct);call .ShowDetailDialog () after the call, this blocks the code call Senduntil the dialog is closed.

I tried the opposite, first calling the code Send, then open the dialog box. But this means that the message handler in the receiving VM does not register in time until the message is sent.

Does anyone know of a solution to prevent call blocking? Or, alternatively, register a ProductVM message handler before sending a message and displaying a dialog?

The following is a summary of related classes:

CustomerOrdersVM (dispatch code):

    private void EditOrder(object obj)
    {
        _dialogService.ShowDetailDialog();    
        Messenger.Default.Send<ProductModel>(SelectedProduct);            
    }

ProductVM (receipt code):

    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 (main VM is registered, ProductVM is independent of this virtual machine):

    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: (contains AppVM views):

<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>
+4
source share
1 answer

You can solve the problem in several ways:

  • Do not use ShowDialog(). Use Show()and make the TopMost dialog box and parent in the main window.
  • ProductView DialogService ( ProductView?)

  • DialogService ( ) , ProductView s

# 2-, ShowDialog, , ProductView. :

class DialogService : IDialogService
{
    Window productView = null;
    ProductView _productView;

    public DialogService()
    {
         _productView = new ProductView();
    }

    public void ShowDetailDialog()
    {
        _productView.ShowDialog();
    }
}
+2

Source: https://habr.com/ru/post/1620653/


All Articles