Получение Unity для разрешения представлений в XAML
-
20-09-2019 - |
Вопрос
Я начинаю работать с MVVM, и я начинаю кое-что понимать.В настоящее время я экспериментирую с фреймворком Cinch, хотя пока еще не привержен ему.
Я вводил ViewModels в представления, используя ссылку на ViewModel в codebehind представления, причем свойство имеет [Зависимость] от него, а в установщике оно устанавливает DataContext в правильное представление, используя Unity.Ловкий трюк, подумал я.
Я пытаюсь заставить свое приложение работать как единое окно с внедренными представлениями (в отличие от нескольких окон и работы с их открытием \ закрытием) Я изменил свои представления с Windows на UserControls и добавил a в главное окно.Это сработало, но ViewModel так и не был введен, предположительно, потому, что XAML не использует Container.Resolve для создания представления, поскольку, когда я создал представление и добавил его вручную в коде с помощью Resolve, была создана [Зависимость].
Как я могу настроить свое окно так, чтобы, если я добавлю представление через XAML или представление будет изменено в результате действия пользовательского интерфейса и т.д., Оно получало его через Unity, чтобы оно могло творить свое волшебство?
Решение
Способ решить вашу проблему - сделать так, чтобы в вашем окне также была ViewModel, а ViewModels из UserControls отображались в качестве свойств в нем.Затем в вашем XAML для окна вы бы просто использовали механизм привязки, чтобы привязать DataContexts UserControl к соответствующим свойствам вашей основной ViewModel.И поскольку эта основная ViewModel разрешена из контейнера Unity, все остальные ViewModel-ы будут вводиться по мере необходимости.
Другие советы
Эта проблема обычно решается с помощью Regions и RegionManager.В главном окне ViewModel создается набор регионов и добавляется в RegionManager.Затем ViewModels могут быть разрешены и добавлены в регион.Коллекция Views.
В XAML регион обычно вводится путем привязки свойства ItemsSource элемента ItemsControl к свойству region основной ViewModel.
Итак, в 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>