29
  <my:DataGridTemplateColumn 
            CanUserResize="False" 
            Width="150" 
            Header="{Binding MeetingName, Source={StaticResource LocStrings}}" 
            SortMemberPath="MeetingName"> 
  </my:DataGridTemplateColumn>

我在 Silverlight 网格控件中有上述列。但它给了我一个 XamlParser 错误,因为我试图设置 Header 属性。有没有人这样做过?我想为多种语言做到这一点。

我绑定到资源的语法也是正确的,因为我在网格外的标签中尝试过它。

4

8 回答 8

28

您不能绑定到 Header,因为它不是 FrameworkElement。您可以通过像这样修改标题模板来使文本动态化:

xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"

<data:DataGridTemplateColumn>   
   <data:DataGridTemplateColumn.HeaderStyle>
       <Style TargetType="dataprimitives:DataGridColumnHeader">
          <Setter Property="Template">
             <Setter.Value>
                <ControlTemplate>                                        
                  <TextBlock Text="{Binding MeetingName, Source={StaticResource LocStrings}}" />                
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </data:DataGridTemplateColumn.HeaderStyle>
</data:DataGridTemplateColumn>
于 2008-09-30T05:38:58.570 回答
14

我的解决方法是使用附加属性自动设置绑定:

public static class DataGridColumnHelper
{
    public static readonly DependencyProperty HeaderBindingProperty = DependencyProperty.RegisterAttached(
        "HeaderBinding",
        typeof(object),
        typeof(DataGridColumnHelper),
        new PropertyMetadata(null, DataGridColumnHelper.HeaderBinding_PropertyChanged));

    public static object GetHeaderBinding(DependencyObject source)
    {
        return (object)source.GetValue(DataGridColumnHelper.HeaderBindingProperty);
    }

    public static void SetHeaderBinding(DependencyObject target, object value)
    {
        target.SetValue(DataGridColumnHelper.HeaderBindingProperty, value);
    }

    private static void HeaderBinding_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataGridColumn column = d as DataGridColumn;

        if (column == null) { return; }

        column.Header = e.NewValue;
    }
}

然后,在 XAML 中:

<data:DataGridTextColumn util:DataGridColumnHelper.HeaderBinding="{Binding MeetingName, Source={StaticResource LocStrings}}" />
于 2011-04-29T15:07:04.263 回答
11

要保留原始标题的视觉样式,请使用 ContentTemplate 而不是 Template:

<Setter Property="ContentTemplate">
<Setter.Value>
    <DataTemplate>
        <Image Source="<image url goes here>"/>
    </DataTemplate>
</Setter.Value>

于 2010-09-02T13:08:02.700 回答
2

找到了一个有趣的解决方法,它也适用于wpflocalizeaddin.codeplex.com

Slyi创建

它使用一个IValueConverter

public class BindingConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value.GetType().Name == "Binding")
        {
            ContentControl cc = new ContentControl();
            cc.SetBinding(ContentControl.ContentProperty, value as Binding);
            return cc;
        }
        else return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {

        return null;
    }
}

还有一种风格DataGridColumnHeader

<UserControl.Resources>
    <local:BindingConverter x:Key="BindCon"/>
    <Style x:Key="ColBinding" TargetType="dataprimitives:DataGridColumnHeader" >
        <Setter Property="ContentTemplate" >
            <Setter.Value>
                <DataTemplate>
                    <ContentPresenter Content="{Binding Converter={StaticResource BindCon}}"  />
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

这样您就可以在Header属性上保留您最喜欢的绑定语法

<Grid x:Name="LayoutRoot" Background="White">
    <StackPanel>
        <TextBox Text="binding header" x:Name="tbox" />

        <data:DataGrid ItemsSource="{Binding AllPeople,Source={StaticResource folks}}" AutoGenerateColumns="False" ColumnHeaderStyle="{StaticResource ColBinding}"  >
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Binding="{Binding ID}" 

                                         Header="{Binding Text, ElementName=tbox}" />
                <data:DataGridTextColumn Binding="{Binding Name}" 

                                         Header="hello" />
            </data:DataGrid.Columns>
        </data:DataGrid>
    </StackPanel>

</Grid>

http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/HeaderBinding.zip

于 2011-03-09T13:19:09.820 回答
2

如上所述,在代码中设置值似乎要简单得多:

dg1.Columns[3].Header = SomeDynamicValue;

避免使用 Setter Property 语法,这在我的情况下似乎会弄乱样式,即使我确实尝试使用 ContentTemplate 和 Template。

我漏掉的一点是,最好使用 dg1.Columns[3].Header符号而不是尝试引用命名列。

我已经命名了我的一个专栏,并试图在代码中引用它,但得到了空异常。使用 Columns[index] 方法效果很好,我可以根据本地化资源为 Header 分配一个文本字符串。

于 2011-11-11T12:04:56.560 回答
1

为什么不简单地在代码中设置它:

dg1.Columns[3].Header = SomeDynamicValue;
于 2010-02-05T16:38:22.153 回答
1

请注意,在 RobSiklos 提供的解决方案中,Source {staticResource...} 是关键,如果您打算像

Binding DataContext.SelectedHistoryTypeItem,RelativeSource={RelativeSource AncestorType=sdk:DataGrid},

它可能不起作用

于 2013-08-16T09:19:11.153 回答
0

我得到了一些绑定解决方案。由于您使用 DataGridTemplateColumn,请将其子类化并添加一个名为 Binding 类型的属性,例如“HeaderBinding”。现在您可以从 XAML 绑定到该属性。接下来,您应该将绑定传播到标题的 DataTemplate 中的 TextBlock。例如,您可以使用该 TextBlock 的 OnLoaded 事件来执行此操作。

 HeaderTextBlock.SetBinding(TextBlock.TextProperty, HeaderBinding);

就是这样。如果您有更多列并且只想使用一个 DataTemplate,那么它会有点复杂,但想法是一样的。

于 2010-04-06T12:42:40.760 回答