DataTemplate Binding question..
- In the following code the property value does not show up in the header but the same does show up in the TextBlock below..What am i missing here?
Thanks in advance..
<HeaderedContentControl Name="ctl">
<HeaderedContentControl.HeaderTemplate>
<DataTemplate >
<Border Background="Blue" BorderThickness="2" CornerRadius="5" >
<StackPanel Orientation="Horizontal" >
<TextBlock Name="lbl" Background="CornflowerBlue" Text="{Binding Path=MyInfo}" Foreground="White" Margin="4"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>
<TextBlock Name="tb" Background="CornflowerBlue" Text="{Binding Path=MyInfo}" Foreground="White" Margin="4"></TextBlock>
</HeaderedContentControl>
MyInfo is a property on the class and i am setting the ctl.DataContext = this;(code behind)
Answers
Actually, it is not a bug. Per our data dev Sam, the ContentTemplate gets expanded in an environment where DataContext is set to the HeaderedContentControl’s Header. Since Header is null, the binding is looking for the property on null, and it fails.
If you said <HeaderedContentControl Header=”{Binding}”>, it would work because the Header is set to an item. In your case, the point of the ContentTemplate is to display the Header property, so all template bindings refer to the Header property. Hope it helps.
Markup:
<Window x:Class="ContentControlDataTemplate2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<HeaderedContentControl Header="{Binding}">
<HeaderedContentControl.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}"/>
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>
</HeaderedContentControl>
<ContentControl Content="{Binding}">
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</StackPanel>
</Window>
Code:
using System.Windows;namespace ContentControlDataTemplate2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Item() { Header = "Header1" };
}
}
public class Item
{
public string Header { set; get; }
}
}
William- Proposed As Answer byWilliam Han - MSFT Wednesday, November 11, 2009 9:27 PM
- Marked As Answer byLinda LiuMSFT, ModeratorFriday, November 13, 2009 10:23 AM
All Replies
Thanks for reporting the issue. It seems like a bug (binding doesn't work after setting DataContent for ContentControl) to me, so I will file a bug to track this issue. Perhaps you can use workaround below that is declaring the type in XAML. Please see example below:
Markup:
<Window x:Class="ContentControlDataTemplate.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ContentControlDataTemplate"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<local:Item x:Key="Item" Header="Header1"/>
</Window.Resources>
<StackPanel>
<HeaderedContentControl>
<HeaderedContentControl.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Source={StaticResource Item}, Path=Header}"/>
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>
</HeaderedContentControl>
</StackPanel>
</Window>
Code:
using System.Windows;namespace ContentControlDataTemplate
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
public class Item
{
public string Header { set; get; }
}
}
WilliamActually, it is not a bug. Per our data dev Sam, the ContentTemplate gets expanded in an environment where DataContext is set to the HeaderedContentControl’s Header. Since Header is null, the binding is looking for the property on null, and it fails.
If you said <HeaderedContentControl Header=”{Binding}”>, it would work because the Header is set to an item. In your case, the point of the ContentTemplate is to display the Header property, so all template bindings refer to the Header property. Hope it helps.
Markup:
<Window x:Class="ContentControlDataTemplate2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<HeaderedContentControl Header="{Binding}">
<HeaderedContentControl.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}"/>
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>
</HeaderedContentControl>
<ContentControl Content="{Binding}">
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</StackPanel>
</Window>
Code:
using System.Windows;namespace ContentControlDataTemplate2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Item() { Header = "Header1" };
}
}
public class Item
{
public string Header { set; get; }
}
}
William- Proposed As Answer byWilliam Han - MSFT Wednesday, November 11, 2009 9:27 PM
- Marked As Answer byLinda LiuMSFT, ModeratorFriday, November 13, 2009 10:23 AM
- Thanks a lot William!


