2009-02-02 4 views
26

Я пытаюсь построить сетку данных, где один из столбцов - это имя шрифта, отображаемое в этом шрифте. Раньше я работал со списком, в котором я определил следующий шаблон:Связывание в текстовом столбце таблицы данных WPF

Это работало нормально. Таким образом, я подправил структуру данных (имя стало Font.Name) и перешел на сетку данных, чтобы попробовать это:

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

Теперь имена шрифтов все отображаются шрифт по умолчанию, и я получаю эту ошибку:

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') 

несколько результатов Google, касающиеся пользовательских элементов управления предлагают изменить свойство от DependencyObject к FrameworkElement, но я должен был бы наследовать DataGridTextColumn и определить свое собственное имущество, чтобы сделать это - должно быть лучше.

Я пробовал несколько разных подходов к связыванию, включая попытку изменить только размер шрифта с отдельным свойством в моем классе данных (т. Е. FontSize="{Binding FontSize}"). Все они привели к той же ошибке, что и выше.

Кто-нибудь знает, что я здесь делаю неправильно?

Edit:

Благодаря ответ Джареда, я обнаружил следующее:

http://blogs.msdn.com/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

Метод выглядит звук, но мне нужно сделать привязку, что ссылки правильный элемент в DataContext для каждой строки, в отличие от совместного использования одного значения для всего столбца.

код позади:

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

XAML:

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

Используя приведенный выше XAML явно не является правильным, потому что DataContext является вся коллекция шрифтов. Но я не могу индексировать коллекцию, так как я не знаю, что это за номер строки (или я?). Есть ли какой-то подход, который я могу использовать для достижения этого?

И вторичный вопрос: почему атрибут Binding работает нормально, даже без DataContext? Он смотрит на ItemsSource вместо этого?

+1

Взгляните на следующее сообщение в блоге. Он подробно описывает проблему, которую вы видите. [Http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx](http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx) По сути проблема заключается в том, что DataGridTextColumn не имеет родителя, из которого можно наследовать привязку, потому что она не является частью логического или визуального дерева. Вы должны настроить контекст наследования, чтобы получить доступ к информации привязки. В блоге, на который я ссылаюсь, подробно описывается, как это сделать. – JaredPar

ответ

21

Ответ Джареда правильный, но я нашел конкретное решение, которое решило мою проблему.

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

Следуя этому примеру, я изменил свое определение DataGridTextColumn к:

<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> 

И мне не нужно беспокоиться о том столбце наследуя DataContext. Это дает мне результат, который я хочу.

1

Попробуйте

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

Иногда связывающая система имеет проблемы с поиском, где объявлена ​​собственность, так что вы должны дать ему некоторую помощь.

+0

В этом конкретном случае FontFamily не унаследован от Control; это свойство в DataGridTextColumn. –

+0

Неплохо, я обнов его до TextBlock, так как это должно быть то, что он будет использовать. –

+0

Все еще нет, с той же оригинальной ошибкой. Я думаю, что у Джареда есть правильная причина. –