FrameworkElement`s DataContext Property does NOT inherit down the element tree

好久不见. 提交于 2019-11-28 11:18:14

DataContext is a property on FrameworkElement (base class for all WPF Controls) and is implemented as a DependencyProperty. That means all the descendant elements in the logical tree share the same DataContext.

The fact that it's a dependency property doesn't imply inheritance... It's true for DataContext, but only because the dependency property has the FrameworkPropertyMetadataOptions.Inherits flag in its metadata.

So the ContentControl should do it with its descendant elements right?

ContentControl is a bit special: the DataContext of its descendants (the visual tree built from the DataTemplate) is actually be the Content of the ContentControl. So if your ContentControl has no content, the DataContext inside it is null.

VinceF

This worked for me:

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

Without the Content="{Binding}", the DataContext was NULL

The last answer (from VinceF) worked for me too.

I wanted to show a usercontrol depending on the value of a property in my viewmodel. So I made a ContentControl with some Style Triggers. Depending on the value of a bind property the trigger sets a specific ContentTemplate containing the specific usercontrol.

The usercontrol was shown right, but its DataContext was always null. So I had to set the Context of the ContentControl to: Content="{Binding}" After that, the UserControls worked fine and had the same DataContext as their parent.

So my XAML looks like that:

In the Resources part I defined two DataTemplates; each one for each UserControl I want to show.

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

The part where I show the UserControl depending on a property is the following:

<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>

after reading this question and previous answers, I prefer using ContentControl with data triggered Content like this:

Controls which will be set as Content of ContentControl:

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

ContentControl which switch own content by DataTrigger in ContentControl style:

<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>

I hope this helps to someone like previous answers to me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!