Force ViewModel Instantiation из XAML - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть вид OutputOptionsView, который содержит несколько UserControls с настройками параметров, которые отображаются в зависимости от выбора в выпадающем списке.

Я создаю Datacontext и Datatemplates для UserControls в OutputOptionsView следующим образом:

<UserControl.Resources>
    <ResourceDictionary>
        <local:OutputOptionsViewModel x:Key="vm" />

        <DataTemplate x:Key="OptionSettings1" DataType="{x:Type views:OptionSettings1View}">
            <views:OptionSettings1View />
        </DataTemplate>

        <DataTemplate x:Key="OptionSettings2" DataType="{x:Type views:OptionSettings2View}">
            <views:OptionSettings2View />
        </DataTemplate>

        ....
    </ResourceDictionary>
</UserControl.Resources>

Отображение OptionSettingsViews обрабатывается следующим образом:

        <ContentControl Name="OutputOptionsContentControl" Content="{Binding}" >
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource OptionSettings1}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding AvailableOptionsListSelectedIndex}" Value="1">
                            <Setter Property="ContentTemplate" Value="{StaticResource OptionSettings2}" />
                        </DataTrigger>
                        ...
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>

ItemsSource и SelectedIndex ComboBox связаны с классом модели представления OutputOptionsViewModel OutputOptionsView:

<ComboBox Name="AvailableOptionsListComboBox" ItemsSource="{Binding AvailableOptionsList}" DisplayMemberPath="OptionTitle" 
                  SelectedIndex="{Binding AvailableOptionsListSelectedIndex, UpdateSourceTrigger=PropertyChanged}"/>

Каждый мой OptionSettings вид также получает ViewModel:

<UserControl.Resources>
    <ResourceDictionary>
        <local:OptionSettings1ViewModel x:Key="vm" />
    </ResourceDictionary>
</UserControl.Resources>

<Grid DataContext="{StaticResource vm}">
...
</Grid>

Теперь моя проблема касается населения из списка. Я создал интерфейс, содержащий OptionTitle, который наследуется каждым OptionsSettingsViewModels. AvailableOptionsList, который является ItemsSouce для выпадающего списка, является списком этого интерфейса.

public List<IOutputOption> AvailableOptionsList { get; set; }

Он будет создан в конструкторе класса OutputOptionsViewModel.

Внутри каждого из OptionSettingsViewModel конструкторов класса я добавляю соответствующий OptionsSettingsViewModel в этот список:

public OptionSettings1ViewModel()
{
    OutputOptionsViewModel.AvailableOptionsList.Add(this);
}

Это приводит к следующей проблеме: поле со списком не заполняется, пока не создаются экземпляры OptionSettingsView, но они не могут быть созданы, потому что их нельзя выбрать из пустого поля со списком. Поэтому я пытаюсь форсировать реализацию OptionSettingsViews.

1 Ответ

0 голосов
/ 15 ноября 2018

Комментарии заставили меня задуматься, есть некоторые основные недоразумения:

[Линн Крамблинг] Я бы полностью переделал это, чтобы всегда создавать экземпляры всех моделей представления, вкладывая их в основную модель представления. Вы будете нуждаться в них, так почему бы просто не раскрутить их в ctor основного виртуального компьютера?

и

[Роланд Дешайн], именно так я и решил на данный момент, однако это означает, что мне нужно установить текст данных в коде каждой опции optionssettingsviewmodel, чего я хотел избежать, если это возможно

Итак, как сказала Линн, вам следует начать с регистрации подвидовых моделей в основной модели представления, и на этом этапе не требуется никакого участия в представлении.

Тогда вы можете определить DataTemplate для моделей представления , а не для представлений , как сейчас.

<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
    <views:OptionSettings1View />
</DataTemplate>

<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
    <views:OptionSettings2View />
</DataTemplate>

Если удалить x:Key и изменить DataType на тип модели представления, шаблоны будут автоматически выбраны для отображения содержимого соответствующего типа.

DataContext ваших вложенных просмотров будет автоматически установлен снаружи. Не создавайте экземпляр под-модели в элементах управления xaml.

В вашем основном OutputOptionsViewModel вы должны разместить коллекцию подмоделей. В вашем выпадающем списке вы должны напрямую использовать эту коллекцию в качестве источника предметов.

Затем просто отбросьте все сложные шаблоны выбора xaml и напрямую привяжите контент к выбранной вами подмодели:

<ContentControl
    Name="OutputOptionsContentControl"
    Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...