WPF DataTemplate Binding
19,053
Solution 1
You are using the ContentTemplate
property incorrectly. From the ContentControl.ContentTemplate
Property page on MSDN:
Gets or sets the data template used to display the content of the ContentControl.
Therefore, when setting this property, you also need to set the Content
property to some sort of data source:
<TabControl>
<TabItem Header="TabItem">
<Label Content="{Binding Path=myString}"/>
</TabItem>
<TabItem Header="TabItem" Content="{Binding Path=myString}">
<TabItem.ContentTemplate>
<DataTemplate>
<Label Content="{Binding}" />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
</TabControl>
Solution 2
<TabItem Content="{Binding myString}" Header="TabItem">
<TabItem.ContentTemplate>
<DataTemplate>
<Label Content="{Binding}" />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
But just so you know, to bind a window on itself, is just not the way to go. I don't know if you did that just for the example, but if not try and create a proper viewModel to bind your window on ;)
Author by
ejones
Updated on June 04, 2022Comments
-
ejones almost 2 years
I discovered when using a ContentTemplate/DataTemplate in a WPF TabControl my Bindings will not work anymore.
I have set up a small example to illustrate:
<Window x:Class="HAND.BindingExample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="BindingExample" Height="506" Width="656" DataContext="{Binding RelativeSource={RelativeSource Self}}" > <Grid> <TabControl HorizontalAlignment="Left" Height="381" VerticalAlignment="Top" Width="608"> <TabItem Header="TabItem"> <Label Content="{Binding Path=myString}"/> </TabItem> <TabItem Header="TabItem"> <TabItem.ContentTemplate> <DataTemplate> <Label Content="{Binding Path=myString}"/> </DataTemplate> </TabItem.ContentTemplate> </TabItem> </TabControl> </Grid> </Window>
Tab1 works as expected, Tab2 is empty.
the code behind:
using System.Windows; namespace HAND { public partial class BindingExample : Window { public string myString { get; set; } public BindingExample() { myString = "Hello Stackoverflow"; InitializeComponent(); } } }
-
Miiite almost 10 yearsI have it running on my machine. Maybe it does not run when you bind a window on itself, which I did not do.
-
ejones almost 10 yearsThank you! This works for my example. I am using a different binding class in my real world program using the MVVM pattern. I still do not understand why your code works and mine doesn't. I will now try to apply the solution of the example to my application.
-
Miiite almost 10 yearsSheridan posted an answer with the same XAML code as mine, but with a better explanation of how the ContentTemplate works. It should help you understanding it
-
ejones almost 10 yearsYes, Thank you both of you!
-
ejones almost 10 yearsSame conclusion as Miiite. Thank you very much also for the good explanation!
-
Sivasubramanian almost 10 yearshi miiite, your answer worked for me, wrongly tested. make an edit to ur answer i will revert the downvote
-
stuzor almost 5 yearswhy do you need to set the Content="{Binding Path=mystring}" in the <TabItem> AND then also set Content="{Binding}" in the <Label>? In this example it doesn't seem necessary for the TabItem.ContentTemplate at all? Wouldn't it work just as well without the Template? I'm trying to understand templates and how I can bind other properties of the Label to parent's DataContext... thanks!
-
Sheridan almost 5 yearsWe data bind the
myString
property to theContent
property to give it some value. Here, that value is just a single string, but it could have been an object with other properties. In theContentTemplate
, we tell it which part of the data bound object we want to display in theLabel
. In this case, we want to bind to the whole string object, so we use{Binding}
to do that. -
wondra almost 4 yearsNoto though: the sample would work only for read-only bindings - if you changed
Label
toTextBox
, myString would never get written back.