Как я могу импортировать мои ViewModels, не ломая MVVM? - PullRequest
1 голос
/ 10 октября 2011
[Export]
public sealed class MainViewModel : NotificationObject
{
    [Import]
    public ISomeService MyService { get; private set; }

    ...
}

Чтобы ВСТАВИТЬ этот класс в DataContext для моего View, я должен пометить его как Export, чтобы MEF создал его экземпляр в каталоге. Проблема в том, что главное окно должно создавать другие окна и передавать заказы, я не уверен, как это сделать, не нарушая подход MVVM.

Я полагаю, что ICommand вызовет что-то на моей MainViewModel, чтобы сгенерировать новую ViewModel, но после этого я не могу действительно заставить новое окно (представление) открыться из ViewModel. Кроме того, я даже не могу создать новую ViewModel из моей MainViewModel, потому что тогда MEF действительно не будет работать, верно?

[Export]
public sealed class MainViewModel : NotificationObject
{
    [Import]
    public ISomeService MyService { get; private set; }

    private ObservableCollection<IOrderViewModel> Orders { get; set; }

    public void OpenOrder(int id)
    {
        //Pseudo-code to ensure that duplicate orders are not opened)

        //Else create/open the new order
        var order = new OrderViewModel(id);

        OpenOrders.Add(order);
    }
}

2 проблемы здесь:

  1. Поскольку я "обновил", сервисы OrderViewModel не загружаются автоматически через MEF.
  2. Как этот код на моем слое ViewModel (соответствующий слой) создает необходимое представление в качестве НОВОГО ОКНА (дочернего элемента основного окна), а затем связывает этот новый OrderViewModel как DataContext?

Ответы [ 2 ]

2 голосов
/ 10 октября 2011

Чтобы избежать «нового» * ​​1001 *, используйте фабрику:

[Export]
public class OrderViewModelFactory
{
    [Import]
    public ISomeDependency ImportedDependency { get; set; }

    public OrderViewModel Create(int id)
    {
        return new OrderViewModel(id, this.ImportedDependency);
    }
}

Затем импортируйте фабрику в свой MainViewModel в качестве зависимости, и MEF позаботится о заполнениивсе как требуется.

Чтобы обойти проблему создания окон, мы создали DialogService, который выполняет что-то вроде:

[Export]
public class DialogService
{
    public bool? ShowDialog(string regionName, object data = null)
    {
        var window = new Window();
        var presenter = new ContentControl();
        presenter.SetProperty(RegionManager.RegionName, regionName);
        window.Content = presenter;
        if (data != null) window.DataContext = data;
        return window.ShowDialog();
    }
}
1 голос
/ 10 октября 2011

Я использую одну технику, которую я называю навигационной службой.Обратите внимание, что это отличается от встроенной в WPF среды навигации.В вашей модели представления может быть вставлен экземпляр напрямую, или вы можете использовать шаблон EventAggregator для запуска запроса на навигацию, который затем обрабатывается службой навигации.Внедрение службы навигации напрямую означает, что она может быть внедрена с другими объектами, такими как ViewModelFactories.Независимо от того, как вы это делаете, в какой-то момент вам понадобится объект, который знает, как создать модель представления, правильно разрешенную вашим контейнером.

...