Как я могу переключаться между представлениями/ViewModels, когда виртуальные машины (и, следовательно, представления) должны принимать параметры конструктора, объекты которых асинхронно инициализируются. Или, альтернативно, есть ли лучший способ предоставить Views/VM эти объекты?Как я могу переключаться между Views/ViewModels, которые предоставляют объекты, которые асинхронно инициализируются раньше времени?
Это моя предыдущая реализация, когда View/VM не использовал параметры конструктора.
MainWindow.xaml
Использует DataTemplates для переключения между просмотрами при изменении ContentControl.
<Window.DataContext>
<viewModels:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type viewModels:InitializerViewModel}">
<userControls:InitializerUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:GameListingViewModel}">
<views:GameListingView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:StreamListingViewModel}">
<views:StreamListingView />
</DataTemplate>
</Window.Resources>
<ContentControl x:Name="ContentSection" Content="{Binding CurrentViewModel, Mode=OneWay}">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="Loaded">
<interactivity:InvokeCommandAction Command="{Binding StartInitializationCommand}"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</ContentControl>
MainWindowViewModel.cs
Создает новые ViewModels, а затем устанавливает CurrentViewModel к соответствующему ViewModel. Когда это изменяется, DataTemplate переключает представление на основе вышеуказанных DataTemplates.
public class MainWindowViewModel : BaseViewModel
{
private InitializerViewModel _initializerViewModel;
public ICommand StartInitializationCommand { get; set; }
public MainWindowViewModel()
{
StartInitializationCommand = new AwaitableDelegateCommand(InitializeAsync);
}
private async Task InitializeAsync()
{
_initializerViewModel = new InitializerViewModel();
CurrentViewModel = _initializerViewModel;
var initializationResult = await _initializerViewModel.InitializeAsync();
if (initializationResult)
{
GameListingViewModel = new GameListingViewModel(_initializerViewModel.MyObject1, _initializerViewModel.MyObject2);
CurrentViewModel = GameListingViewModel;
}
}
}
GameListingView.xaml (это один из виртуальных машин я переключаюсь в и):
Ранее определено DataContext в XAML через:
<UserControl.DataContext>
<viewModels:GameListingViewModel />
</UserControl.DataContext>-->
Все вышеперечисленные работы как и ожидалось.
Теперь, благодаря новой функциональности, эти ViewModels нужно получить 1 или несколько объектов, чтобы функционировать, поэтому я хочу, чтобы передать их в конструктор. В результате я больше не могу определять DataContext в xaml, но я могу использовать код для их создания.
public GameListingView(ConfigSettings configSettings, GameBoxHelper gameBoxHelper)
{
InitializeComponent();
DataContext = new GameListingViewModel(configSettings, gameBoxHelper);
}
Проблема заключается в это требует конструктора зрения, чтобы также принимать в соответствующих объектах (в противном случае, где бы я получить эти объекты из?), Что делает DataTemplate назад в MainWindow.xaml
больше не работает.
Xaml сообщения об ошибке: «. Тип„GameListingView“не может использоваться в качестве элемента объекта, поскольку она не является общедоступной или не определяет открытый конструктор без параметров или преобразователь типа конструктора по умолчанию не найден»
Важно, что объекты, которые будут переданы в эти ViewModels, не будут готовы немедленно; MainWindowViewModel инициализирует их заранее, что делается асинхронно. В приведенном выше сообщении об ошибке, я думаю, можно использовать TypeConverter
(привязка подлежащих передаче объектов к параметрам и назначение их в xaml в качестве параметров для TypeConverter), но я не вижу, как это будет работать, поскольку они не сразу готово (асинхронно инициализировано).
Для справки: намерение заключается в том, что при загрузке приложения вся инициализация выполняется спереди (считывание параметров конфигурации из файловой системы, извлечение некоторых данных из веб-интерфейсов и т. Д.), Так что она сразу же готова, когда это необходимо остальное приложение более отзывчивое. Я бы предпочел не перемещать асинхронную инициализацию объектов на виртуальные машины, которые их используют.
Я не использую рамки MVVM.
Учитывая все это, мой вопрос заключается в том, как я могу продолжать переключать свои представления/виртуальные машины, предоставляя им объекты, которые асинхронно инициализируются раньше времени?
Я думаю, что вы можете использовать DependancyProperty в представлении и обновить вид модель, когда они изменяют. – Ron
Можете ли вы привести пример, как это будет работать? – JBC
Рассмотрите дизайн, ориентированный на viewmodel, где ваша основная модель просмотра имеет дочерние режимы просмотра (или коллекции дочерних моделей) в качестве свойств, а дочерние модели просмотра могут иметь собственные собственные свойства VM. Вместо представлений, создающих свои собственные режимы просмотра, используйте 'DataTemplate' для неявного назначения представлений в viewmodels. ' ' - любой тип 'BlahVM', если для него есть неявный' DataTemplate', вы получите это в пользовательском интерфейсе. «BlahVM» может быть объявлен как объект, его родитель может в течение дня переключать разные дочерние виртуальные машины. –