WPF + MvvM + Призма - PullRequest
       17

WPF + MvvM + Призма

4 голосов
/ 05 мая 2010

Я новичок в мире Wpf & Mvvm, но я нашел пару примеров и только что обнаружил, что есть другой способ создания экземпляра модели. Я хотел бы знать лучший / правильный способ сделать это. оба способа используют Unity

Что я кричу:

var navigatorView = new MainView();
navigatorView.DataContext = m_Container.Resolve<INavigatorViewModel>();
m_RegionManager.Regions["NavigatorRegion"].Add(navigatorView);

Что я сделал:

var navigatorView = m_Container.Resolve<MainView>;
m_RegionManager.Regions["NavigatorRegion"].Add(navigatorView);

и я изменил конструктор, чтобы получить viewmodel, чтобы я мог указать ему текст данных:

public MainView(NavigatorViewModel navigatorViewModel)
{
 this.DataContext = navigatorViewModel;
}  

Другие примеры, которые я нашел, например:

...vm = new viewmodel 
...m = new model
v.model = vm;

получить / установить DataContext

ура

Ответы [ 2 ]

8 голосов
/ 06 мая 2010

Мне нравится предложение Игоря, но без модели представления, обладающей знанием представления. Я предпочитаю, чтобы мои зависимости шли в одном направлении (View -> ViewModel -> Model).

Что я делаю, так это ViewModel-First и просто DataTemplate модели представления. Итак, я делаю это:

MainViewModel mainViewModel = container.Resolve<MainViewModel>();

region.Add(mainViewModel, "MainView");
region.Activate(mainViewModel);

С добавлением ViewModel -> Отображение вида, выполненное с помощью таблицы данных WPF (хотя я не думаю, что такой подход возможен с Silverlight)

App.xaml:

<Application.Resources>
     <DataTemplate DataType="{x:Type viewModels:MainViewModel}">
          <views:MainView />
     </DataTemplate>
</Application.Resources>

Вот и все! Мне нравится этот подход. Мне нравится, как это похоже на магию. Он также имеет следующие преимущества:

  • Не нужно модифицировать конструкторы в соответствии с отображением
  • Не нужно регистрировать тип для IMyViewModel в контейнере ... вы можете работать с конкретными типами. Мне нравится хранить свои регистрации в службах приложений, таких как IViewRegistry или ILogger ... такого рода вещи
  • Вы можете изменить отображение, используя ресурсы, относящиеся к определенному представлению, в котором находится регион (это хорошо, если вы хотите повторно использовать ваши ViewModels, но хотите, чтобы они выглядели по-разному в разных областях приложения
0 голосов
/ 06 мая 2010

То, что у вас есть, имеет смысл, и в обоих случаях это подход View-first к созданию модели представления. То есть представление создает ViewModel. В исходном примере модель представления создается вне представления (и иногда упоминается как шаблон брака ), но, насколько мне известно, это то же самое - создание представления создает модель представления.

Если это соответствует вашим потребностям, придерживайтесь этого. Другой подход, на который вы можете обратить внимание, - это сначала ViewModel, где viewmodel берет зависимость от вида следующим образом:

//In the bare-bones(i.e. no WPF dependencies) common interface assembly

interfac IView {
  void ApplyViewModel(object viewmodel);
}    

interface IMainView : IView {
  //this interface can actually be empty.
  //It's only used to map to implementation.
}

//In the ViewModel assembly

class MainViewModel {
  public MainViewModel(IMainView view) {
    view.ApplyViewModel(this);
  }
}

public partial class MainView : UserControl, IMainView {
  void ApplyViewModel(object viewmodel){
    DataContext = viewmodel;
  }
}

Тогда вы можете добавить это представление так:

IRegion region = regionManager.Regions["MainRegion"];

//This might look strange as we are resolving the class to itself, not an interface to the class
//This is OK, we want to take advantage of the DI container 
//to resolve the viewmodel's dependencies for us,
//not just to resolve an interface to the class.
MainViewModel mainViewModel = container.Resolve<MainViewModel>();

region.Add(mainViewModel.View, "MainView");
region.Activate(ordersView.View);
...