Datacontext not set when using a DataTemplate

Lloyd Sheen 1,476 Reputation points
2020-11-04T16:03:25.2+00:00

I have an app in early development. In it there is a TabItem. At first I had the content as simply XAML following the <TabItem line. All datacontexts within the content worked.

Then the next thing I did was to move the content to resources (the tabitem finds the resource and uses it) and use ContentTemplate to use the resource. Now all the datacontext in the content are NULL.

I am at a complete loss to explain or fix this.

Part of the XAML:

<TabItem x:Name="TSTabItem" Header="Test Search" ContentTemplate="{StaticResource PlayerDetails}" >
</TabItem>

The PlayerDetails datatemplate is a copy of the content that I first used and all TextBlock fields show so I know it is being used. Is there something else that I need to do to get the DataContext to work?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,756 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Emon Haque 3,176 Reputation points
    2020-11-05T01:05:21.1+00:00

    There're:

    TemplateBinding Property
    Binding Property, RelativeSource={RelativeSource TemplatedParent}
    Binding DataContext.Property, Source={x:Reference elementName} 
    Binding DataContext.Property, RelativeSource={RelativeSource AncestorType={x:Type Control}}
    Binding Property, Source={x:Static staticpProperty}
    

    etc. If you want to customize a Control, create Custom Control instead of StaticResource ..., that's easier, and use it like <custom:MyTabControl ..../> in your UserControl/Page. In your case, I think either or one of the first two should work. I don't have much use of TabControl in my apps, whenever I need, I use it like:

        <TabControl ItemsSource="{Binding MyListOfViews}"
                    SelectedItem="{Binding SelectedView}"
                    TabStripPlacement="Right"
                    BorderThickness="0">
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Content" Value="{Binding SomeUserControl}"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="TabItem">
                                <Grid Background="Transparent" ToolTip="{Binding Tip}">
                                    <Path Data="{Binding GeoString}"
                                            Fill="Black"
                                            Stretch="Uniform"
                                            Width="16" Height="16"
                                            Margin="5 10 0 0"
                                            x:Name="path"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="path" Property="Fill" Value="Red"/>
                                    </Trigger>
    
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="path" Property="Fill" Value="Blue"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>
    

    where each item in MyListOfViews has 3 properties, SomeUserControl, Tip and GeoString.

    0 comments No comments

  2. Lloyd Sheen 1,476 Reputation points
    2020-11-05T15:41:17.167+00:00

    The above post was as a result of my inputting for 10 minutes all the details of my tests. When attempting to post it failed. This forum format should go back to old was as I never had a problem with it.

    Ok so one more try.

    Generic XAML:

    <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:HockeyAppNew">

    <DataTemplate x:Key="PlayerDetails">
        <Grid x:Name="SeachGrid" 
                              DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext.theSeachVM}" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
    
            <Grid.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="14"></Setter>
                    <Setter Property="FontWeight" Value="Bold"></Setter>
                </Style>
            </Grid.Resources>
    
            <StackPanel Grid.Column="0">
                <TextBox x:Name="TheSearchText" Grid.Column="0" Text="{Binding searchString,UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2"></TextBox>
                <ListBox ItemsSource="{Binding PlayerSeachItems}" SelectedItem="{Binding selectedPlayer}"></ListBox>
            </StackPanel>
    
            <Grid Grid.Column="1" DataContext="{Binding theSearchedPlayer}" 
                                  Visibility="Visible">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition ></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
    
                <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical" >
                    <TextBlock Grid.Row="0" Text="{Binding fullName}" HorizontalAlignment="Center" FontSize="24" FontWeight="Bold"></TextBlock>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition></RowDefinition>
                            <RowDefinition></RowDefinition>
                            <RowDefinition></RowDefinition>
                            <RowDefinition></RowDefinition>
                        </Grid.RowDefinitions>
    
                        <local:PropertyDisplay Grid.Column="0" Grid.Row="0" theHeader="Position :" theValue="{Binding PositionName}" ></local:PropertyDisplay>
                        <local:PropertyDisplay Grid.Column="0" Grid.Row="1" theHeader="Country of birth :" theValue="{Binding birthCountry}" ></local:PropertyDisplay>
                        <local:PropertyDisplay Grid.Column="0" Grid.Row="2" theHeader="City of birth :" theValue="{Binding birthCity}" ></local:PropertyDisplay>
    
                        <local:PropertyDisplay Grid.Column="1" Grid.Row="0" theHeader="Number :" theValue="{Binding jerseyNumber}" ></local:PropertyDisplay>
                        <local:PropertyDisplay Grid.Column="1" Grid.Row="1" theHeader="Age :" theValue="{Binding currentAge}" ></local:PropertyDisplay>
                        <local:PropertyDisplay Grid.Column="1" Grid.Row="2" theHeader="Height :" theValue="{Binding height}" ></local:PropertyDisplay>
                        <local:PropertyDisplay Grid.Column="1" Grid.Row="3" theHeader="Weight :" theValue="{Binding weight}" ></local:PropertyDisplay>
    
                    </Grid>
                </StackPanel>
    
                <Image Grid.Row="0" Grid.Column="1" Source="{Binding PlayerLogo}" Width="168">
                </Image>
    
                <Grid Grid.Row="3" Grid.ColumnSpan="2" Margin="0,10,0,0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto">
                        </RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
    
                    <CheckBox Grid.Row="0" IsChecked="{Binding showOnlyNHL}">
                        Show Only NHL
                    </CheckBox>
    
    
                    <DataGrid Grid.Row="1"  ItemsSource="{Binding fullPlayerStats,NotifyOnTargetUpdated=True}" Visibility="Visible" 
                                                CanUserAddRows="False" IsReadOnly="True" FrozenColumnCount="2" AutoGenerateColumns="False" >
                        <DataGrid.RowStyle>
                            <Style TargetType="DataGridRow">
                                <Setter Property="Background" Value="{Binding RowBackGround}"/>
                                <Setter Property="Visibility" Value="{Binding RowVisibility}"></Setter>
                            </Style>
                        </DataGrid.RowStyle>
    
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Team" Binding="{Binding team}">
                                <DataGridTextColumn.CellStyle>
                                    <Style TargetType="DataGridCell">
                                        <Setter Property="ToolTip">
                                            <Setter.Value>
                                                <ToolTip>
                                                    <StackPanel Orientation="Horizontal">
                                                        <TextBlock Text="League - " FontWeight="SemiBold"  />
                                                        <TextBlock Text="{Binding league}" FontWeight="Bold" />
                                                    </StackPanel>
                                                </ToolTip>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </DataGridTextColumn.CellStyle>
                            </DataGridTextColumn>
                            <DataGridTextColumn Header="Season" Binding="{Binding season}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Games" Binding="{Binding games}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Goals" Binding="{Binding goals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Assists" Binding="{Binding assists}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Points" Binding="{Binding points}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PIM" Binding="{Binding PIM}"></DataGridTextColumn>
                            <DataGridTextColumn Header="+/-" Binding="{Binding plusMinus}"></DataGridTextColumn>
                            <DataGridTextColumn Header="TOI" Binding="{Binding timeOnIce_t}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP TOI" Binding="{Binding powerPlaytimeOnIce_t}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH TOI" Binding="{Binding shortHandedTimeOnIce_t}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Even TOI" Binding="{Binding evenTimeOnIce_t}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shots" Binding="{Binding shots}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Hits" Binding="{Binding hits}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Goals" Binding="{Binding powerPlayGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Points" Binding="{Binding powerPlayPoints}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Faceoff %" Binding="{Binding faceOffPct}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shot %" Binding="{Binding shotPct}"></DataGridTextColumn>
                            <DataGridTextColumn Header="GW Goals" Binding="{Binding gameWinningGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="OT Goals" Binding="{Binding overTimeGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Goals" Binding="{Binding shortHandedGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Points" Binding="{Binding shortHandedPoints}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Blocked" Binding="{Binding blocked}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shifts" Binding="{Binding shifts}"></DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
    
                    <DataGrid Grid.Row="1" ItemsSource="{Binding fullPlayerStats,NotifyOnTargetUpdated=True}" Visibility="{Binding ShowGoalie}"
                                                CanUserAddRows="False" IsReadOnly="True" FrozenColumnCount="2" AutoGenerateColumns="False" >
                        <DataGrid.RowStyle>
                            <Style TargetType="DataGridRow">
                                <Setter Property="Background" Value="{Binding RowBackGround}"/>
                                <Setter Property="Visibility" Value="{Binding RowVisibility}"></Setter>
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Team" Binding="{Binding team}">
                                <DataGridTextColumn.CellStyle>
                                    <Style TargetType="DataGridCell">
                                        <Setter Property="ToolTip">
                                            <Setter.Value>
                                                <ToolTip>
                                                    <StackPanel Orientation="Horizontal">
                                                        <TextBlock Text="League - " FontWeight="SemiBold"  />
                                                        <TextBlock Text="{Binding league}" FontWeight="Bold" />
                                                    </StackPanel>
                                                </ToolTip>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </DataGridTextColumn.CellStyle>
                            </DataGridTextColumn>
                            <DataGridTextColumn Header="Season" Binding="{Binding season}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Games" Binding="{Binding games}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Games Started" Binding="{Binding gamesStarted}"></DataGridTextColumn>
    
                            <DataGridTextColumn Header="Shots" Binding="{Binding shots}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Hits" Binding="{Binding hits}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Goals" Binding="{Binding powerPlayGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Points" Binding="{Binding powerPlayPoints}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Faceoff %" Binding="{Binding faceOffPct}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shot %" Binding="{Binding shotPct}"></DataGridTextColumn>
                            <DataGridTextColumn Header="GW Goals" Binding="{Binding gameWinningGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="OT Goals" Binding="{Binding overTimeGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Goals" Binding="{Binding shortHandedGoals}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Points" Binding="{Binding shortHandedPoints}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Blocked" Binding="{Binding blocked}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Goals Against" Binding="{Binding goalsAgainst}"></DataGridTextColumn>
                            <DataGridTextColumn Header="GAAverage" Binding="{Binding goalAgainstAverage}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Wins" Binding="{Binding wins}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Ties" Binding="{Binding ties}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Losses" Binding="{Binding losses}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Saves" Binding="{Binding saves}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Save %" Binding="{Binding savePercentage}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shutouts" Binding="{Binding shutouts}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Shots" Binding="{Binding shotsAgainst}"></DataGridTextColumn>
    
                            <DataGridTextColumn Header="PP Saves" Binding="{Binding powerPlaySaves}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Shots" Binding="{Binding powerPlayShots}"></DataGridTextColumn>
                            <DataGridTextColumn Header="PP Save %" Binding="{Binding powerPlaySavePercentage}"></DataGridTextColumn>
    
                            <DataGridTextColumn Header="SH Shots" Binding="{Binding shortHandedShots}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Save %" Binding="{Binding shortHandedSavePercentage}"></DataGridTextColumn>
                            <DataGridTextColumn Header="SH Saves" Binding="{Binding shortHandedSaves}"></DataGridTextColumn>
    
                            <DataGridTextColumn Header="E Saves" Binding="{Binding evenSaves}"></DataGridTextColumn>
                            <DataGridTextColumn Header="E Shots" Binding="{Binding evenShots}"></DataGridTextColumn>
                            <DataGridTextColumn Header="E Save %" Binding="{Binding evenStrengthSavePercentage}"></DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
    
                </Grid>
            </Grid>
        </Grid>
    </DataTemplate>
    
    <DataTemplate x:Key="TestTemplate">
        <Button Content="Its a button"></Button>
    </DataTemplate>
    
    <Style TargetType="{x:Type local:CustomControl1}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                    <TabItem x:Name="TUC" Header="Test CC">
                        <TextBlock Text="Let try this"></TextBlock>
                    </TabItem>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    </ResourceDictionary>

    Class code:

    Public Class CustomControl1
    Inherits System.Windows.Controls.Control

    Shared Sub New()
        'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
        'This style is defined in themes\generic.xaml
        DefaultStyleKeyProperty.OverrideMetadata(GetType(CustomControl1), new FrameworkPropertyMetadata(GetType(CustomControl1)))
    End Sub
    
    Private _TestProp As String
    
    Public Property TestProp() As String
        Get
            Return _TestProp
        End Get
        Set(ByVal value As String)
            _TestProp = value
            'RaiseChanged("TestProp")
        End Set
    End Property
    
    Private Sub TUC_DataContextChanged(sender As Object, e As DependencyPropertyChangedEventArgs) Handles Me.DataContextChanged
        Dim i As Integer = 1
        Dim dc As VMSearch
        If e.NewValue IsNot Nothing Then
            dc = e.NewValue
            dc.HeaderString = TestProp
        End If
    End Sub
    

    End Class

    Doing this test I did get a TabItem with no Header info. It was selectable and the content was what was defined for the Header.

    Changing the code to inherit from TabItem test again added a TabItem but this time with Header info but it was not selectable.

    Basically CustomControl does not work in any way that would be expected.

    Any ideas?


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.