2015-12-18 3 views
4

Я использую Messenger class для того, чтобы отправлять данные между моделями просмотра. Существует AppView, который содержит два основных вида в элементе управления контентом и до сих пор не имел проблемы с отправкой/получением данных таким образом.Как зарегистрировать обработчик сообщений перед вызовом ShowDialog()?

Выпуск:

Теперь я добавил ProductView, который показывает отдельное диалоговое окно в APPVIEW. Но когда я вызываю Messenger.Default.Send<ProductModel>(SelectedProduct); после вызова .ShowDetailDialog(), это блокирует вызов кода 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 (Main ВМ зарегистрированы, 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> 

ответ

2

Вы мог бы решить эту проблему несколькими способами:

  1. Не использовать ShowDialog(). Используйте Show() и создайте диалоговое окно TopMost и родительское в главном окне.
  2. Зарегистрируйте ProductView в конструкторе DialogService (вы действительно нужен новый ProductView каждый раз, так или иначе?)

  3. сделать DialogService (или служебный класс внутри него) регистрирует во время строительства для сообщения , а затем передать сообщение на любые отображаемые ProductView s

Лично мне нравится # 2-, так как вы используете ShowDialog, это означает, что только один ProductView когда-либо необходимо в то время.Например:

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

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

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

Хорошо в # 2, Регистром ProductView, вы имеете в виду передать его в CTOR, как это: Public DialogService (ProductView вид) {this._view = вид} Тогда вызова также могли бы вы предоставить фрагмент кода на решение # 1, сделав диалог родительским для appView? –

+0

Я привел пример # 2 в редактировании. Для # 1 см. Https://msdn.microsoft.com/en-us/library/system.windows.window.topmost(v=vs.110).aspx и http://stackoverflow.com/questions/27462682/ wpf-set-parent-window –

+0

Я реализовал # 2, зарегистрировав ProductView в DialogService(). Итак .. _productView.ShowDialog(); не работает, но почему-то _productView.Show(); сделал произведение. Любые идеи, почему это так? –

Смежные вопросы