The column header of the DataGrid is not a FrameWork element for some reason, and so you cannot use bindings to set things like the header text. Please correct me if that is wrong of if that has changed with .NET 4.0 (I am using the latest WPFToolkit from CodePlex now).
I am trying to use the DataGrid for a time sheet presentation where the day's date should be part of the header text (ie, "Sun, Nov 01"), and I have the following in my XAML:
<dg:DataGrid.Columns>
<dg:DataGridTextColumn Header="Description" Width="Auto" Binding="{Binding Description}" IsReadOnly="True"/>
<dg:DataGridTextColumn Header="Mon" Width="50" Binding="{Binding Allocations[0].Amount}" />
... every other day of the week ....
<dg:DataGridTextColumn Header="Sun" Width="50" Binding="{Binding Allocations[6].Amount}" />
<dg:DataGridTextColumn Header="Total" MinWidth="50" Binding="{Binding TotalAllocatedAmount}" IsReadOnly="True" />
</dg:DataGrid.Columns>
I'd like to use the same AllocationViewModel I am using for data (ie, "{Binding Allocations[0].Amount}" and bind it's DisplayName property to the header text. Can someone show me how to do that? If I have to use a static resource, how can I get the DataContext in there?
EDIT ---------------- PREFERRED WORK-AROUND
Josh Smith had posted about a DataContextSpy awhile back, and it is the cleanest workaround I have come across to this problem. Here is the class that makes it work:
/// <summary>
/// Workaround to enable <see cref="DataContext"/> bindings in situations where the DataContext is not redily available.
/// </summary>
/// <remarks>http://blogs.infragistics.com/blogs/josh_smith/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx</remarks>
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();
}
}
With this in place, I can hijack the DC I need in xaml:
<dg:DataGrid.Resources>
<behavior:DataContextSpy x:Key="spy" DataContext="{Binding Allocations}" />
</dg:DataGrid.Resources>
And then apply as needed via binding:
<dg:DataGridTextColumn Header="{Binding Source={StaticResource spy}, Path=DataContext[0].DisplayName}"
Width="50" Binding="{Binding Allocations[0].Amount}" />
Suh-weet!