Получение единства для разрешения представлений в XAML - PullRequest
4 голосов
/ 15 ноября 2009

Я начинаю с MVVM и начинаю понимать вещи. В настоящее время я экспериментирую со структурой Cinch, хотя пока еще не привержен ей.
Я внедрял ViewModel в Views, используя ссылку на ViewModel в коде позади представления, со свойством, имеющим [Dependency], и в установщике он устанавливает DataContext в правильное представление, используя Unity. Уловка, подумал я.

Я пытаюсь заставить мое приложение работать как единое окно с внедренными представлениями (в отличие от нескольких окон и их открытия / закрытия) Я изменил свои представления с Windows на UserControls и добавил в главное окно. Это сработало, но ViewModel никогда не вводился, предположительно потому, что XAML не использует Container.Resolve для создания представления, как когда я создал представление и добавил его вручную в коде с помощью Resolve, была создана [Dependency] .

Как я могу настроить свое окно, чтобы, если я добавлю представление через XAML, или представление изменилось в результате действия пользовательского интерфейса и т. Д., Оно получило его через Unity, чтобы оно могло творить чудеса?

Ответы [ 2 ]

4 голосов
/ 16 ноября 2009

Эта проблема обычно решается с помощью Regions и RegionManager. В главном окне ViewModel создается набор регионов и добавляется в RegionManager. Затем ViewModels можно разрешить и добавить в коллекцию Region.Views.

В XAML Регион обычно внедряется с помощью свойства ItemsSource элемента ItemsControl, связанного со свойством region основной модели представления.

Итак, на главном экране ViewModel у вас будет что-то вроде этого:

    public class TestScreenViewModel
{
    public const string MainRegionKey = "TestScreenViewModel.MainRegion";

    public TestScreenViewModel(IUnityContainer container, IRegionManager regionManager)
    {
        this.MainRegion = new Region();
        regionManager.Regions.Add(MainRegionKey, this.MainRegion);
    }

    public Region MainRegion { get; set; }
}

Это обычно разрешается в вашем IModule

        #region IModule Members

    public void Initialize()
    {
        RegisterViewsAndServices();

        var vm = Container.Resolve<SelectorViewModel>();
        var mainScreen = Container.Resolve<TestScreenViewModel>();
        mainScreen.MainRegion.Add(vm);

        var mainView = ContentManager.AddContentView("Test harness", mainScreen);
    }

    #endregion

И XAML-представление вашего шаблона выглядит примерно так:

    <DataTemplate DataType="{x:Type TestModule:TestScreenViewModel}">
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
        <StackPanel>
            <ItemsControl ItemsSource="{Binding Path=MainRegion.Views}" />
        </StackPanel>
    </ScrollViewer>
</DataTemplate>
3 голосов
/ 15 ноября 2009

Способ решения вашей проблемы состоит в том, чтобы заставить ваше окно также иметь ViewModel, с ViewModels из UserControls, выставленным в качестве свойств для него. Затем в вашем XAML для окна вы просто используете механизм привязки, чтобы связать DataContexts UserControl с надлежащими свойствами вашего основного ViewModel. И поскольку этот основной ViewModel разрешен из контейнера Unity, он будет вставлять все другие ViewModel-ы по мере необходимости.

...