Reputation: 521
Can someone tell me if this is possible. I have a WPF datagrid and I'd like to bind the column headers of the datagrid to properties/fields in the code behind.
So heres what I've tried. This is my column code.
<DataGridTextColumn Header="{Binding ElementName=frmAssetPPM, Path=HeaderProperty}"
And this is what I've added to the window xaml.
<Window .... Name="frmAssetPPM">
And this is my property definition in the code behind:
private const string HeaderPropertyConstant = "Property";
private string _headerProperty = HeaderPropertyConstant;
public string HeaderProperty
{
get { return _headerProperty; }
set { _headerProperty = value; }
}
However, when I run the application, I'm getting this error message displayed in the Output window in VS.
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=HeaderProperty; DataItem=null; target element is 'DataGridTextColumn' (HashCode=47624635); target property is 'Header' (type 'Object')
Can someone tell me what I'm doing wrong? Or if I can even do this? I read somewhere that columns are a separate object and this sometimes leads to complications.
Upvotes: 2
Views: 2178
Reputation: 6316
Some things are tough to bind because they are not part of the Visual tree, such as popups or in your case - datagrid headers. A well known workaround is to use Josh Smith's DataContextSpy. Basically you instantiate it as a resource and give it the binding. Then use that instance elsewhere, where you can tap into it's data context. There are plenty examples on the web, but to get you started, something like this should work..
<DataGrid.Resources>
<DataContextSpy x:Key="dcSpy"
DataContext="{Binding ElementName=frmAssetPPM, Path=HeaderProperty}"/>
....
then your binding will work:
<DataGridTextColumn Header="{Binding Source={StaticResource dcSpy}, Path=DataContext}"
here's Josh Smith's code if you don't find it on the web:
public class DataContextSpy : Freezable
{
public DataContextSpy ()
{
// This binding allows the spy to inherit a DataContext.
BindingOperations.SetBinding (this, DataContextProperty, new Binding ());
}
public object DataContext
{
get { return GetValue (DataContextProperty); }
set { SetValue (DataContextProperty, value); }
}
// Borrow the DataContext dependency property from FrameworkElement.
public static readonly DependencyProperty DataContextProperty = FrameworkElement
.DataContextProperty.AddOwner (typeof (DataContextSpy));
protected override Freezable CreateInstanceCore ()
{
// We are required to override this abstract method.
throw new NotImplementedException ();
}
}
Upvotes: 2