FrameworkElement的DataContext属性不继承元素树

时间:2010-12-18 21:56:28

标签: wpf datacontext inheritance frameworkelement

Hello WPF Pros至少我希望你们中的一些人读到这个!

DataContext是FrameworkElement(所有WPF控件的基类)上的属性,并作为DependencyProperty实现。这意味着逻辑树中的所有后代元素共享相同的DataContext。

所以ContentControl应该使用它的后代元素吗?

我的情况是这个案例,我想知道造成这种不当行为的原因是什么?!

你了解更多关于它的信息请阅读这个帖子(不要在这里复制所有内容)麻烦开始......:

WPF: Can not find the Trigger target 'cc'. The target must appear before any Setters, Triggers

并用简短的话来说:我在ContentControl中的DataTemplates确实有一个死的DataContext,意味着没有绑定到它,实际上是不可能的......

ContentControl中的每个元素都在DataContext属性中设置了NOTHING

4 个答案:

答案 0 :(得分:21)

  

DataContext是一个属性   FrameworkElement(所有的基类)   WPF控件)并实现为   的DependencyProperty。这意味着所有的   逻辑中的后代元素   tree共享相同的DataContext。

它是一个依赖属性的事实并不意味着继承......对于DataContext来说这是正确的,但仅仅因为依赖属性在其元数据中有FrameworkPropertyMetadataOptions.Inherits标志。

  

所以ContentControl应该这样做   它的后代元素对吗?

ContentControl有点特别:DataContext的后代(DataTemplate构建的可视树)实际上是Content ContentControl }。因此,如果您的ContentControl没有内容,则其中的DataContext为空。

答案 1 :(得分:13)

这对我有用:

<ContentControl ContentTemplate="{StaticResource NotesTemplate}"
                Content="{Binding}"
                DataContext="{Binding HeightField}"/>

没有Content="{Binding}",DataContext为NULL

答案 2 :(得分:0)

最后一个答案(来自VinceF)也适合我。

我想根据viewmodel中属性的值显示usercontrol。所以我用一些样式触发器创建了一个ContentControl。根据绑定属性的值,触发器设置包含特定用户控件的特定ContentTemplate。

用户控件显示正确,但其DataContext始终为null。所以我必须将ContentControl的Context设置为:Content="{Binding}"之后,UserControls工作正常,并且与其父级具有相同的DataContext。

所以我的XAML看起来像这样:

在参考资料部分,我定义了两个DataTemplates;每个我想要显示的UserControl。

<DataTemplate x:Key="ViewA">
    <namespace:UserControlA/>
</DataTemplate>
<DataTemplate x:Key="ViewB">
    <namespace:UserControlB/>
</DataTemplate>

我根据属性显示UserControl的部分如下:

<ContentControl Content="{Binding}">
    <ContentControl.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Property}" Value="0">
                    <Setter Property="ContentControl.ContentTemplate" Value="{StaticResource ViewA}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Property}" Value="1">
                    <Setter Property="ContentControl.ContentTemplate" Value="{StaticResource ViewB}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

答案 3 :(得分:0)

在阅读了这个问题和之前的答案之后,我更喜欢将ContentControl与数据触发的内容一起使用,如下所示:

将设置为ContentControl内容的控件:

<TextBox x:Key="ViewA">
   ...
</TextBox>
<ComboBox x:Key="ViewB">
   ...
</ComboBox>

ContentControl,它由ContentControl样式中的DataTrigger切换自己的内容:

<ContentControl>
  <ContentControl.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=Property}" Value="0">
                <Setter Property="Content" Value="{StaticResource ViewA}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Property}" Value="1">
                <Setter Property="Content" Value="{StaticResource ViewB}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
  </ContentControl.Style>
</ContentControl>

我希望这对以前给我答案的人有所帮助。