Prism MVVM - Добавить дочерний вид в родительский вид без использования областей и инъекций, просто XAML - PullRequest
1 голос
/ 07 января 2010

Я довольно новичок в Silverlight и шаблоне MVVM / Prism, так что это может быть глупым вопросом.

У меня есть View, в котором есть пользовательские элементы управления.Эти пользовательские элементы управления на самом деле тоже являются представлениями и имеют ViewModel для управления ими.

В настоящее время для добавления этих «дочерних» представлений к используемому представлению (см. Рис. 1), а затем в ViewModel у меня есть инициализация.() метод, который разрешает дочерний вид и внедряет его (см. Рис.2).

Рис.1

<UserControl
x:Class="ProjectA.Module.Screens.Views.PlatformScreenView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Regions="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"
>
<Grid x:Name="LayoutRoot">
    <ContentControl
        Regions:RegionManager.RegionName="FeaturesSelectionControl"
        />
</Grid>

Рис.2

public void Initialise()
{
    IRegion featuresRegion = _regionManager.Regions["FeaturesSelectionControl"];
    featuresRegion.Add(_container.Resolve<IFeatureSelectionControlViewModel>().View);
}

Мой вопрос: нужно ли это делать для каждого элемента управления, который я хочу добавить?Я понимаю, почему это работает таким образом, но мне кажется, что это довольно много кода, а также мне нужно отслеживать все имена регионов и следить за тем, чтобы у меня не было конфликтов и т. Д. Есть ли более простой способ сделать это без регионов итолько в XAML?

Я видел фрагмент XAML в StackOverflow здесь , но не уверен, как он работает, и если это то, что я хочу -

<ContentControl Content="{Binding SmartFormViewModel}"/>

Любойпомощь очень ценится.

Джеймс

1 Ответ

1 голос
/ 07 января 2010

Изменить после уточнения:

Похоже, вы вообще не хотите использовать RegionManager, и это нормально. Тогда я хотел бы предложить следующее:

Создайте интерфейс для ваших модулей, чтобы использовать его для регистрации методов создания представлений:

public interface IViewRegistry
{
     void RegisterMainView(Func<object> ViewCreationDelegate);
}

Ваши модули будут использовать это так:

public MyModule : IModule
{
     IViewRegistry _registry;
     public MyModule(IViewRegistry registry)
     {
          _registry = registry;
     }

     public void Initialize()
     {
          _registry.RegisterMainView(() =>
          {
               var vm = new MyViewModel();
               var view = new MyView();
               var view.DataContext = vm;
               return view;
          });
     }
}

Затем в вашей оболочке вы сначала реализуете представление реестра (это упрощение ... вы, вероятно, захотите что-то более надежное)

public ViewRegistry : IViewRegistry
{
     public static List<Func<object>> ViewFactories
     {
           get { return _viewFactories; }
     }
     static List<Func<object>> _viewFactories = new List<Func<object>>();
     public void RegisterMainView(Func<object> viewFactory)
     {
          _viewFactories.Add(viewFactory);
     }
}

И, наконец, вот как ваша оболочка будет показывать это. Вот сначала его ViewModel:

public ShellViewModel : ViewModel
{
     public ObservableCollection<object> MainViews
     {
          ...
     }

     public ShellViewModel()
     {
          MainViews = new ObservableCollection<object>(ViewRegistry.Select(factory => factory()));
     }
}

А вот ваше мнение (смотри, ма, не RegionManager!):

<UserControl ...>
   <Grid>
     <ItemsControl ItemsSource="{Binding MainViews}" />
   </Grid>
</UserControl>

Менеджер по регионам пытается дать вам все, что я здесь написал, плюс много точек расширения, но если вам не нравится RegionManager или вы обнаружите, что он по каким-то причинам не соответствует вашим потребностям, это как бы вы сделали это в Silverlight без него.


Дополнительные правки:

После еще одного комментария от OP, я думаю, что понимаю, что OP просто хочет показать представление в другом представлении без использования RegionManager. Похоже, что ОП использует RegionManager для отображения каждого представления на экране, что, вероятно, излишне.

Сценарий, который мне дали, включал в себя адресное представление и связанную ViewModel, используемую из другого родительского элемента управления. Вот что я делаю (правильно или неправильно):

<UserControl x:Class="Views.MyParentView" ...>
<StackPanel>
     <TextBlock>Blah blah blah some other stuff... blah blah</TextBlock>
     <myViews:AddressView DataContext="{Binding AddressVM}" />
</StackPanel>
</UserControl>

А вот родительская точка зрения viewModel:

public ParentViewModel : ViewModel
{
     public AddressViewModel AddressVM
     {
          ...
     }

     public ParentViewModel()
     {
          AddressVM = new AddressViewModel();
     }
}

Вот и все. Это избавляет вас от необходимости слишком усердно работать, чтобы показать эти взгляды.

RegionManager действительно подходит для отделения представления родительского контейнера от подпредставления, но если оба они живут в одном и том же месте (один и тот же модуль / сборка), нет причин использовать RegionManager для отображения этих представлений.

...