我有一个视图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>
ComboBox的 ItemsSource
和SelectedIndex
绑定到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>
现在,我的问题涉及组合框的人口。我创建了一个接口,其中包含每个OptionsSettingsViewModels
继承的OptionTitle。组合框的AvailableOptionsList
的{{1}}是此接口的列表。
ItemsSouce
它将在public List<IOutputOption> AvailableOptionsList { get; set; }
类的构造方法中实例化。
在每个OutputOptionsViewModel
类构造函数中,我将各自的OptionSettingsViewModel
添加到此列表中:
OptionsSettingsViewModel
这将导致以下问题:只要没有实例化OptionSettingsViews,就不会填充组合框,但是由于无法从空组合框中选择它们,因此无法实例化它们。 因此,我希望强制OptionSettingsViews的实例化。
答案 0 :(得分:1)
这些评论让我觉得,有一些基本的误解:
[Lynn Crumbling]我将完全重新设计它,以便始终实例化所有视图模型,并将它们嵌套在mainviewmodel下。您将需要它们,为什么不直接将它们放在主vm的ctor中呢?
和
[Roland Deschain]实际上是我目前解决的方法,但是这意味着我必须在每个optionssettingsviewmodel的代码背后设置数据上下文,这是我想避免的
因此,正如Lynn所说,您应该首先在主视图模型中注册子视图模型,此时无需任何视图参与。
然后,您可以为视图模型定义DataTemplate
,而不是像现在一样为视图定义。
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
通过删除x:Key
并将DataType
更改为viewmodel类型,将自动选择模板以显示相应类型的内容。
子视图的DataContext将自动从外部设置。不要在xaml控件中实例化子视图模型。
在您的主OutputOptionsViewModel
中,您应该托管子视图模型的集合。在组合框中,您应该直接将此集合用作itemssource。
然后只需删除所有复杂的模板选择xaml并将内容直接绑定到您选择的子视图模型:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />