Reputation: 1903
I'm trying to bind the datagrid column header to the date selected in the datepicker. For example:
+--------------------------------------+
| 1/29/2018 |
+--------------------------------------+
|1/29/2018|1/30/2018|1/31/2018|2/1/2018|
+--------------------------------------+
|Available|Leave |Available|Leave |
|Leave |Leave |Available|Leave |
+--------------------------------------+
using:
<StackPanel>
<DatePicker HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Top" Text="{Binding SelectedDate}"/>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding UserScheduleViewModels}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" />
<DataGridTextColumn Header="{Binding SelectedDate}" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
However, my first column is showing Name like it should, but the date for the 2nd column is just blank. Any ideas?
Upvotes: 0
Views: 109
Reputation: 25623
The data context does not pass through the DataGrid.Columns
collection, so placing a Binding
on a column definition won't work without some added indirection.
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding UserScheduleViewModels}">
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Value="{Binding SelectedDate}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" />
<DataGridTextColumn Header="{Binding Source={StaticResource proxy}, Path=Value}" />
</DataGrid.Columns>
</DataGrid>
BindingProxy
is a utility class that you can use to work around situations like this. The idea is that you place one in a resource dictionary and use it as an intermediary. You bind its Value
to the otherwise inaccessible data you need, then reference it as the binding Source
from outside of the inheritance context. As with all static resources, the BindingProxy
resource declaration must appear before the Binding
that points to it (in Xaml parse order).
public class BindingProxy : Freezable
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value",
typeof(object),
typeof(BindingProxy),
new PropertyMetadata(default(object)));
public object Value
{
get { return (object)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
}
Although using a proxy object may seem less than ideal, it has the benefit of working in most situations where you need to use bindings from outside the normal inheritance context. Learning this approach (and why it works) may help you in similar situations in the future. For example, this will come in handy if you ever need bindings inside of a ToolTip
.
Upvotes: 1
Reputation: 3182
<StackPanel>
<DatePicker HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Top" Text="{Binding SelectedDate}"/>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding UserScheduleViewModels}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" />
<DataGridTextColumn>
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=DataGrid},Path=DataContext.SelectedDate}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
Upvotes: 1