I'm trying to bind a data on one of my columns to data that's in my page's ViewModel (as opposed to the objects that the grid is bound to).
What I have below was recommended here, to no avail.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding ElementName=LayoutRoot, Path=DataContext.JUNK}"></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
In my ViewModel
public string JUNK { get; set; }
Which is set to "HELLO"
in the ViewModel's constructor
Does anyone see what I'm doing wrong?
EDIT
Here's the entire XAML. Relevant column is all the way at the bottom, in the grid within the grid
ALSO - I'm having trouble getting my entire source into here again (not sure if it's citrix or what) but I took that same exact binding expression that's not working in the datagrid's button, and I dropped it onto the Text of a plain old TextBlock apart from the grid, and it worked like a charm. I also added a new dummy text column to the grid, and used that same binding expression for the text, and it still did not work. It seems this binding expression is fine, but refuses to work anywhere near the grid.
<UserControl x:Class="MainApp.WPF.ucFmvHistoryDisplayGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="1000" x:Name="LayoutRoot">
<UserControl.Resources>
<Style x:Name="rightAlignedColumn" x:Key="rightAlignedColumn" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Name="centerAlignedColumn" x:Key="centerAlignedColumn" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid>
<DataGrid x:Name="dbTop" ItemsSource="{Binding PropertyGroupSource}" HorizontalAlignment="Left" Background="White" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" AutoGenerateColumns="False" Grid.Row="1" Width="800">
<DataGrid.Columns>
<DataGridTextColumn Width="120" Header="Property Num" Binding="{Binding PropertyNum}"></DataGridTextColumn>
<DataGridTextColumn Width="120" Header="Alt Description" Binding="{Binding AltDescription}"></DataGridTextColumn>
<DataGridTextColumn Width="80" Header="County" Binding="{Binding County}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="State" Binding="{Binding State}" ElementStyle="{StaticResource centerAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="85" Header="Phase" Binding="{Binding Phase}"></DataGridTextColumn>
<DataGridTextColumn Width="85" Header="FMV" Binding="{Binding FmvTotal}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="Assessed Value" Binding="{Binding AssessedValueTotal}"></DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border Margin="5" BorderBrush="Black" BorderThickness="1">
<DataGrid Margin="5" Background="White" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding PropertyFmvSource}">
<DataGrid.Columns>
<DataGridTextColumn Width="125" Header="County Acct Num" Binding="{Binding Property.CountyAccountNum, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="80" Header="City" Binding="{Binding Property.City, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="80" Header="Jurisdiction" Binding="{Binding Property.Jurisdiction, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="80" Header="FMV Date" Binding="{Binding MostRecentFMV.FMVDate, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="FMV" Binding="{Binding MostRecentFMV.FMV, StringFormat=N0}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="85" Header="Assess Ratio" Binding="{Binding MostRecentFMV.AssessmentRatio, StringFormat=N3}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTextColumn Width="105" Header="Assessed Value" Binding="{Binding MostRecentFMV.AssessedValue, StringFormat=N0}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding ElementName=LayoutRoot, Path=DataContext.JUNK}"></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
Binding to the DataContext of the containing DataGrid using a RelativeSource binding should work:
<Button Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=2}, Path=DataContext.JUNK}"></Button>
As you've nested the DataGrids, the AncestorLevel must be set to "2" to Bind to the DataContext of the outermost DataGrid.
Update
@Danny Shisler's answer is correct. Leaving this answer since it shows how to do Bindings inside of DataGridColumn
which isn't in the Visual Tree and doesn't have a DataContext
Here is a blog post that presents a workaround for this issue: http://blogs.infragistics.com/blogs/josh_smith/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx
The workaround is to create a DataContextSpy that looks like this
DataContextSpy
public class DataContextSpy
: Freezable // Enable ElementName and DataContext bindings
{
public DataContextSpy()
{
// This binding allows the spy to inherit a DataContext.
BindingOperations.SetBinding(this, DataContextProperty, new Binding());
}
public object DataContext
{
get { return (object)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();
}
}
And then you can use an instance of DataContextSpy
as the Source for the Bindings in the DataGridColumn
s like this
<Grid Name="LayoutRoot">
<Grid.Resources>
<local:DataContextSpy x:Key="dataContextSpy" />
</Grid.Resources>
<DataGrid ...>
<DataGrid.Columns>
<DataGridTemplateColumn Header="{Binding Path=DataContext.JUNK,
Source={StaticResource dataContextSpy}}">
<!--..-->
</DataGridTemplateColumn>
<!--..-->
</DataGrid.Columns>
</DataGrid>
</Grid>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With