2012-04-02 2 views
1

Я переписываю проект в WPF с использованием рамки Caliburn. Я пришел из мира C++, так что некоторые трудности выясняют даже простейшие вещи ...Caliburn MVVM диалог WPF с действием ОК

Итак, предположим, что у меня есть: MainView, MainViewModel, DialogView, DialogViewModel.

В MainView.xaml: ...

<MenuItem Name="Dialog" Header="Dialog"></MenuItem> 

... Caliburn ограничивает его метода в MainViewModel:

public void Dialog() 
     { 
      dynamic settings = new ExpandoObject(); 
      settings.WindowStartupLocation = WindowStartupLocation.Manual; 
      _windowManager.ShowWindow(new DialogViewModel(_windowManager), null, settings); 
     } 

Он отлично работает, появляется диалоговое окно.

Теперь, в этом диалоге у меня есть:

<TextBox Name="Dimension1"/> 
<TextBox Name="Dimension2"/> 

плюс, другие Textboxes, флажков и т.д. Тогда Есть OK и Отмена:

<Button Content="OK" Name="OK"></Button> 
<Button Content="Cancel" Name "Cancel"></Button> 

Теперь, как это прямо сейчас они привязаны к методам OK() и Cancel() в DialogViewModel, и я не могу понять или найти информацию о том, как с ними работать в DialogViewModel.
Я нашел пример, когда создается класс DialogResultsAction, я связан мой OK/Отмена кнопки с методами в этом классе, но не может понять, как действовать дальше ...

Можете ли вы посоветовать мне, в каком направлении следует Я хожу?

+0

Вы смотрели на образцы, которые приходят с Caliburn микро? Если вы не используете микро, вы можете посмотреть на него. –

+0

Я использую Micro. Посмотрим на образцы. Можете ли вы порекомендовать конкретный вариант? – user1298416

+0

Я смотрю HelloWindowManager - когда пользователь нажимает на определенную кнопку в диалоговом окне, он передает datacontext кнопки в ViewModel.В моем случае у меня есть около 20 текстовых полей, флажки, радиокнопки в одном диалоговом окне, должен ли я передавать их все как параметры в ViewModel или есть более элегантный способ сделать это? – user1298416

ответ

1

Я не уверен, что это то, что вы ищете, но вы можете рассматривать DialogViewModel, как и любой другой экран. В этом примере Ok и Cancel привязаны к соответствующим методам. Технически вы можете установить x:Name="TryClose" для имени кнопки отмены, но я назвал его Cancel для этого примера.

В методе Open в ShellViewModel вы можете предварительно установить значения в диалоговом окне перед его отображением. И после того, как результат будет возвращен, так как у вас есть ссылка на него, вы также можете прочитать эти значения.

Открытый метод в ShellViewModel:

public void Open() 
    { 
     var dialogViewModel = IoC.Get<DialogViewModel>(); 
     dialogViewModel.Dimension1 = "123"; 
     dialogViewModel.Dimension2 = "456"; 
     var result = WindowManager.ShowDialog(dialogViewModel); 
     if (dialogViewModel.MyDialogResult == DialogResult.OK) return; 

     //do stuff with results    
     var dim1 = dialogViewModel.Dimension1; 
    } 

DialogView:

<Grid> 
     <StackPanel> 
      <TextBlock x:Name="Dimension1" /> 
      <TextBlock x:Name="Dimension2" /> 
     </StackPanel> 
     <StackPanel Height="50" 
        Orientation="Horizontal"> 
      <Button x:Name="Ok" 
        Content="Ok" /> 
      <Button x:Name="Cancel" 
        Content="cancel" /> 
     </StackPanel> 
    </Grid> 

DialogViewmodel:

[Export(typeof (DialogViewModel))] 
    public class DialogViewModel : Screen 
    { 
     private string _dimension1; 
     public string Dimension1 
     { 
      get { return _dimension1; } 
      set 
      { 
       _dimension1 = value; 
       NotifyOfPropertyChange(() => Dimension1); 
      } 
     } 
     private string _dimension2; 
     public string Dimension2 
     { 
      get { return _dimension2; } 
      set 
      { 
       _dimension2 = value; 
       NotifyOfPropertyChange(() => Dimension2); 
      } 
     } 

     public void Ok() 
    { 
     //Do stuff 
     MyDialogResult = DialogResult.OK; 
     TryClose(); 
    } 

    public void Cancel() 
    { 
     MyDialogResult = DialogResult.Cancel; 
     TryClose();   
    } 
+0

Спасибо! Это именно то, что я искал. – user1298416

0

Если ваша модель ViewModel основана на IScreen, используйте Close в методе Ok или Cancel. Если вам нужно вернуть результат, я бы предложил использовать IEventAggregator, чтобы вернуть результат родительскому. Если вам действительно нужно, вы можете использовать GetView(), чтобы получить представление, связанное с viewmodel, применить его к правильному типу и установить результат (при условии, что представление имеет результат, я не использовал класс Dialog) ,

+0

Моя модель основана на PropertyChangedBase, IShell, где IShell является пустой inteface (я нашел этот пример где-то). Если я добавлю IScreen, а затем воспользуюсь Close() в моем методе OK() - как у меня будут различные значения, такие как _dimension1, _dimension, обновленные в MainViewModel? Я прочитаю больше о IEventAggregator ... Можете ли вы предложить какие-нибудь примеры? Спасибо! – user1298416

+0

Экран (или IScreen) происходит из PropertyChangedBase. Я бы получил от Screen, поскольку он имеет гораздо больше доступного для него, и вам не придется реализовывать весь IScreen. –

+0

Спасибо за объяснение! – user1298416

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