在Wpf中使用TabControl在视图之间切换时如何摆脱BindingException

时间:2018-11-28 13:58:06

标签: c# wpf data-binding

在我的ViewModel中,我收藏了TabItem。 每个TabItem包含一个名称和另一个ViewModel(从BaseModel继承到INotifyPropertyChanged)。基于此ViewModel的属性,XAML决定应将哪个View放置在每个选项卡控件项的ContentTemplate中。

我正在使用mvvm模式,并且可以通过在选项卡之间切换来完成这项工作。问题是我收到绑定异常。很难解释。

错误消息如下:

  

System.Windows.Data错误:40:BindingExpression路径错误:在“对象”“ DisplayModel1”(HashCode = 8229676)上找不到“ ExtraText”属性。 BindingExpression:Path = ExtraText; DataItem ='DisplayModel1'(HashCode = 8229676);目标元素是'标签'(名称='');目标属性为“内容”(类型为“对象”)

要重现该错误,可以使用下面的代码,并提供示例数据。 这是我的起始窗口的XAML:

<Window.Resources>
    <DataTemplate x:Key="Model1Template" DataType="{x:Type local:BaseModel}">
        <local:DisplayModel1View />
    </DataTemplate>
    <DataTemplate x:Key="Model2Template" DataType="{x:Type local:BaseModel}">
        <local:DisplayModel2View />
    </DataTemplate>
</Window.Resources>
<Grid>
    <TabControl ItemsSource="{Binding TabItems}">
        <TabControl.Resources>
            <Style TargetType="{x:Type TabItem}">
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
            </Style>
        </TabControl.Resources>
        <TabControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:TabModel}">
                <Label DockPanel.Dock="Left" Content="{Binding Name}"></Label>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate DataType="{x:Type local:BaseModel}">
                <ContentControl Content="{Binding ViewModel, Mode=TwoWay}">
                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Setter Property="ContentTemplate" Value="{StaticResource Model1Template}" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=ViewModel.ModelType}" Value="Model2">
                                    <Setter Property="ContentTemplate" Value="{StaticResource Model2Template}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Grid>

我定义了两个保存特定视图的模板。在TabControl.ContentTemplate中,我正在检查enumViewModel的{​​{1}}值。

这些是可能的视图:

DisplayModel1View

TabModel

DisplayModel2View

<Grid>
    <Label Content="{Binding Name}"></Label>        
</Grid>

您可以看到,基础视图模型具有不同的属性。在<StackPanel> <Label Content="{Binding Name}"></Label> <Label Content="{Binding ExtraText}"></Label> </StackPanel> 中,您可以看到错误消息中提到的属性DisplayModel2View

最后但并非最不重要的模型:

ExtraText

1 个答案:

答案 0 :(得分:1)

实际上,您不需要该ModelType属性。让WPF根据视图模型的类型找出用于哪个视图模型的视图。

首先从DataTemplate中删除Window.Resources。卸下扳机。 将用于{strong>具体视图模型类型的DataTemplate(而非ViewModelBase)放置在TabControl的资源中(这是为了使这些{{1} }标签控件的本地-我们只希望它们在此处应用。

然后,您将得到类似的内容:

DataTemplate