绑定在WPF数据网格文本列中

时间:2009-02-02 06:50:14

标签: .net wpf data-binding xaml datagrid

我正在尝试构建一个数据网格,其中一列是以该字体显示的字体名称。以前,我正在使用列表框,我在其中定义了以下模板:

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

这很好用。所以,我调整了数据结构(Name变为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并定义我自己的属性才能这样做 - 必须有更好的方法。

我尝试了几种不同的绑定方法,包括尝试在我的数据类中使用distinct属性更改字体大小(即FontSize="{Binding FontSize}")。它们都导致了与上述相同的错误。

任何人都知道我在这里做错了吗?

修改

感谢Jared的回复,我发现了以下内容:

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是整个字体集合。但我不能索引集合,因为我不知道行号是什么(或者我?)。我可以用一些方法来实现这个目标吗?

还有一个第二个问题 - 为什么即使没有DataContext,Binding属性似乎也能正常工作?它是在寻找ItemsSource吗?

2 个答案:

答案 0 :(得分:22)

Jared的回答是正确的,但我找到了解决问题的具体解决方案。

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 :(得分:1)

尝试

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

有时绑定系统在查找声明属性的位置时遇到问题,因此您需要给它一些帮助。