Question

I'm trying to do something basic (I think!), but I've got a problem. I have got a TabControl and 3 TabItems. The 2 first items must be untouched, and I want to apply a dataTemplate on the third tabItem, so I used a DataTemplateSelector. This is OK, it works. But then, I want to fill data in the third tabItem with my datamodel. Binding is not working because my DataContext is always "null" in the tabItem. How can I set the DataContext in the tabItem created by the dataTemplate ? Here is my code :

XAML :

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="910" Width="1200">

<Window.Resources>
    <DataTemplate x:Key="configurationTemplate" DataType="{x:Type local:ConfigurationDatamodel}">
        <local:ConfigurationTemplateUC DataContext="{Binding DataContext.ConfigurationDatamodel}" />
    </DataTemplate>

    <local:TabItemTemplateSelector ConfigurationTemplate="{StaticResource configurationTemplate}" x:Key="tabItemTemplateSelector"/>
</Window.Resources>

<Grid>
    <TabControl Height="800" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="tabControl1" VerticalAlignment="Top" ContentTemplateSelector="{StaticResource tabItemTemplateSelector}">
        <TabItem Header="TabItem1" Name="tabItem1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <some stuff />
        </TabItem>
        <TabItem Header="TabItem2" Name="tabItem2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <some stuff />
        </TabItem>
        <TabItem Header="TabItem3" Name="tabItem3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">

        </TabItem>
    </TabControl>
</Grid>
</Window>

UserControl of my DataTemplate :

<UserControl x:Class="WpfApplication1.ConfigurationTemplateUC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="800" d:DesignWidth="1000">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Label Content="File name : " Height="28" HorizontalAlignment="Left" Margin="50,43,0,0" Name="label1" VerticalAlignment="Top" FontSize="16"/>
    <Label Content="{Binding Path=File}" FontSize="16" Height="28" HorizontalAlignment="Left" Margin="160,43,0,0" Name="label2" VerticalAlignment="Top" Width="324" />
</Grid>
</UserControl>

Datamodel :

public class ConfigurationDatamodel
{
    private string file;

    public string File
    {
        get { return this.file; }
        set 
        { 
            this.file= value;
        }
    }

    public ConfigurationDatamodel()
    {}

    public ConfigurationDatamodel(string file)
    {
        this.file= file;
    }
}

Code-behind :

public MainWindow()
    {
        ConfigurationDatamodel dt1 = new ConfigurationDatamodel("example.txt");
        InitializeComponent();

        tabItem3.DataContext = dt1;
    }

There is no binding errors in the console, but the label containing the filename is always empty. The DataContext of the UserControl "ConfigurationTemplateUC" is always "null".

Any thoughts?

EDIT

If I set the DataContext in the contructor of the UserControl, it works :

public ConfigurationTemplateUC()
    {
        InitializeComponent();
        ConfigurationDatamodel dt1 = new ConfigurationDatamodel("example.txt");
        this.DataContext = dt1;
    }

How can I set this dataContext with the DataTemplate ?

Was it helpful?

Solution

In your DataTemplate, Remove the DataContext binding from

<local:ConfigurationTemplateUC DataContext="{Binding DataContext.ConfigurationDatamodel}" />

...leaving only

<local:ConfigurationTemplateUC />

UI in a DataTemplate automatically gets the bound data as its DataContext, so in your case you override the correct DataTemplate with a path to something that can't be found.

EDIT:

Also, you don't need a DataTemplateSelector to do this. You can remove the selector and instead simply use TabItem.ContentTemplate:

<TabItem Header="TabItem3" Name="tabItem3" ContentTemplate="{StaticResource configurationTemplate}" >
    ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top