I have a DataGrid inside a secondary TabItem and I wanted to bind some data from the view model to the header. I was able to bind data to the header of the DataGrid in the primary TabItem but the same code doesn't work for the secondary TabItem. I followed the answer for the following question but it still isn't working and I'm not sure what is wrong. I'm not really sure if my data context is incorrect or if my binding is not set up correctly.
Binding not working in DataGrid column header when inside non-primary TabItem
Here is my code:
XAML
<Window xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Class="TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Test Window" Height="645" Width="900">
<StackPanel Orientation="Vertical">
<TabControl>
<TabItem Name="Primary_Tab" Header="Primary Tab">
<!--Mock Data Grid-->
</TabItem>
<TabItem Name="Secondary_Tab" Header="Secondary Tab">
<DataGrid Height="500" ItemsSource="{Binding GridDetails}" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Name" Header="Name" Binding="{Binding Path='Name', Mode=OneTime}" IsReadOnly="True" Width="200" />
<DataGridTextColumn x:Name="ID" Header="ID" Binding="{Binding Path='ID', Mode=OneTime}" IsReadOnly="True" Width="100">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="NumClaims" Binding="{Binding Path='NumClaims', Mode=OneTime}" IsReadOnly="True" Width="100">
<DataGridTextColumn.Header>
<StackPanel>
<TextBlock Text="Claims"/>
<TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}, Path=DataContext}" Text="{Binding TotalClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="NewClaims" Binding="{Binding Path='NumNewClaims', Mode=OneTime}" IsReadOnly="True" Width="80">
<DataGridTextColumn.Header>
<StackPanel>
<TextBlock Text="New Claims"/>
<TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}, Path=DataContext}" Text="{Binding TotalNewClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="{Binding NumNewClaims}"/>
</Style>
</DataGridTextColumn.CellStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>
</StackPanel>
</Window>
View Model
public class TestWindowViewModel : ViewModelBase
{
private ObservableCollection<GridDetailModel> _gridDetails;
public ObservableCollection<GridDetailModel> GridDetails
{
get
{
return _gridDetails;
}
set
{
SetProperty(ref _gridDetails, value);
}
}
private string _totalClaims = "0";
public string TotalClaims
{
get
{
return _totalClaims;
}
set
{
SetProperty(ref _totalClaims, value);
}
}
private string _totalNewClaims = "0";
public string TotalNewClaims
{
get
{
return _totalNewClaims;
}
set
{
SetProperty(ref _totalNewClaims, value);
}
}
}
Binding Proxy Class
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
Any help would be greatly appreciated.
I finally managed to fix the binding issues. It seems like I had a bunch of unnecessary binding context code that was interfering with the proxy binding. For anyone who is having the same issue in the future this is what worked for me. Note that I didn't have to change the view model or the BindingProxy class at all. Just needed some work on the XAML portion.
<Window xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Class="TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mxlns:local="clr-namespace:MyNamespace"
mc:Ignorable="d"
Title="Test Window" Height="645" Width="900">
<StackPanel Orientation="Vertical">
<TabControl>
<TabItem Name="Primary_Tab" Header="Primary Tab">
<!--Mock Data Grid-->
</TabItem>
<TabItem Name="Secondary_Tab" Header="Secondary Tab">
<DataGrid Height="500" ItemsSource="{Binding GridDetails}" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Name" Header="Name" Binding="{Binding Path='Name', Mode=OneTime}" IsReadOnly="True" Width="200" />
<DataGridTextColumn x:Name="ID" Header="ID" Binding="{Binding Path='ID', Mode=OneTime}" IsReadOnly="True" Width="100">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="NumClaims" Binding="{Binding Path='NumClaims', Mode=OneTime}" IsReadOnly="True" Width="100">
<DataGridTextColumn.Header>
<StackPanel>
<TextBlock Text="Claims"/>
<TextBlock Text="{Binding Path=Data.TotalClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}" />
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="NewClaims" Binding="{Binding Path='NumNewClaims', Mode=OneTime}" IsReadOnly="True" Width="80">
<DataGridTextColumn.Header>
<StackPanel>
<TextBlock Text="New Claims"/>
<TextBlock Text="{Binding Path=Data.TotalNewClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}" />
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="{Binding NumNewClaims}"/>
</Style>
</DataGridTextColumn.CellStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>
</StackPanel>
</Window>