Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding in a WPF data grid text column

I'm trying to build a data grid where one of the columns is a font name displayed in that font. Previously, I was working with a list box where I had defined the following template:

<TextBlock Text="{Binding Path=Name}" FontFamily="{Binding Path=Name}"/> 

This worked just fine. So, I tweaked the data structure (Name became Font.Name) and moved onto a data grid to try this:

<dg:DataGridTextColumn Binding="{Binding Font.Name}"      FontFamily="{Binding Font.Name}" IsReadOnly="True" Header="Font"/> 

Now the font names are all displayed in the default font, and I get this error:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or  FrameworkContentElement for target element.  BindingExpression:Path=Font.Name; DataItem=null; target element is  'DataGridTextColumn' (HashCode=56915998); target property is 'FontFamily'  (type 'FontFamily') 

A few Google results dealing with custom controls suggest changing the property from DependencyObject to FrameworkElement, but I'd have to inherit DataGridTextColumn and define my own property to do so - there must be a better way.

I've tried several different approaches to the binding, including attempting to change just the font size with a distinct property in my data class (i.e., FontSize="{Binding FontSize}"). They've all resulted in the same error as above.

Anyone know what I'm doing wrong here?

Edit:

Thanks to Jared's reply, I found the following:

https://docs.microsoft.com/en-us/archive/blogs/jaimer/forwarding-the-datagrids-datacontext-to-its-columns

The method looks sound, but I need to make a binding that references the correct element in the DataContext for each row, as opposed to sharing a single value for the entire column.

Code behind:

fontDataGrid.DataContext = from font      in new InstalledFontCollection().Families; 

XAML:

Binding="{Binding Font.Name}" FontFamily="{Binding (FrameworkElement.DataContext).Font.Name,      RelativeSource={x:Static RelativeSource.Self}}" 

Using the above XAML clearly isn't correct, because DataContext is the entire collection of fonts. But I can't index the collection, since I don't know what the row number is (or do I?). Is there some approach I can use to achieve this?

And a secondary question - why does the Binding attribute seem to work just fine, even without the DataContext? Is it looking at ItemsSource instead?

like image 565
Matthew Maravillas Avatar asked Feb 02 '09 06:02

Matthew Maravillas


2 Answers

Jared's answer is correct, but I've found a concrete solution that's solved my problem.

http://blogs.msdn.com/vinsibal/archive/2008/12/17/wpf-datagrid-dynamically-updating-datagridcomboboxcolumn.aspx

Following this example, I changed my DataGridTextColumn definition to:

<dg:DataGridTextColumn Binding="{Binding Font.Name}" IsReadOnly="True" Header="Font">     <dg:DataGridTextColumn.ElementStyle>         <Style TargetType="TextBlock">             <Setter Property="FontFamily" Value="{Binding Font.Name}" />         </Style>     </dg:DataGridTextColumn.ElementStyle> </dg:DataGridTextColumn> 

And I don't need to worry about the column inheriting the DataContext. This gives me the result I want.

like image 178
Matthew Maravillas Avatar answered Sep 23 '22 15:09

Matthew Maravillas


Try

TextBlock.FontFamily="{Binding Font.Name}" 

Sometimes the binding system has a problem finding where a property is declared so you need to give it some help.

like image 44
Bryan Anderson Avatar answered Sep 22 '22 15:09

Bryan Anderson