Can a column header on a DataGrid be bound?

Jan 30, 2009 at 7:19 PM

I have a user control  that contains a DataGrid with 2 columns, one for X values and one for Y values. The user control has 2 dependency properties (XLabel and YLabel) on it that specify the titles that should be used for each of the columns. I am attempting to bind the header for the columns to these properties but have not been successful.

The user control is called PiecewiseLinearFuncEditor. Here is the XAML (edited for brevity):

<UserControl x:Class="Ardent.TherAn.UI.Control.PiecewiseLinearFuncEditor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    Name="editor">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Controls:DataGrid x:Name="functionPoints"
             ItemsSource="{Binding FunctionPoints,ElementName=editor,NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}"
             AutoGenerateColumns="False"                                   
             Grid.Row="1" HeadersVisibility="Column" >
                <Controls:DataGrid.Columns>
                    <Controls:DataGridTextColumn x:Name="xColumn" Header="{Binding XLabel,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control:PiecewiseLinearFuncEditor}}}" Binding="{Binding X,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True}" Width="100" />
                    <Controls:DataGridTextColumn x:Name="yColumn" Header="Y" Binding="{Binding Y,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True}" Width="100"/>
                </Controls:DataGrid.Columns>
            </Controls:DataGrid>
        </Grid>
</UserControl>

The code behind contains the following:
    public partial class PiecewiseLinearFuncEditor : UserControl
    {
        public static readonly DependencyProperty xLabel = DependencyProperty.Register("XLabel", typeof (string), typeof (PiecewiseLinearFuncEditor));
        public static readonly DependencyProperty yLabel = DependencyProperty.Register("YLabel", typeof (string), typeof (PiecewiseLinearFuncEditor));
        
        public string XLabel {
            get { return (string) GetValue(xLabel); }
            set { SetValue(xLabel, value); }
        }

        public string YLabel {
            get { return (string) GetValue(yLabel); }
            set { SetValue(yLabel, value); }
        }

When I run this I get the following error when the first column header tries to bind:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Ardent.TherAn.UI.Control.PiecewiseLinearFuncEditor', AncestorLevel='1''. BindingExpression:Path=XLabel; DataItem=null; target element is 'DataGridTextColumn' (HashCode=37722553); target property is 'Header' (type 'Object')

I have also tried using a binding with ElementName like this:

Header="{Binding YLabel,ElementName=editor}"

This was not successful either.

Does anyone know how to do this binding?

Thanks,

Geoff

Coordinator
Feb 5, 2009 at 3:50 AM
You will need to hack it by forwarding the DataContext.  See this post, http://blogs.msdn.com/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx.