动态设置Silverlight DataGrid列的标题文本

时间:2008-09-30 03:41:02

标签: silverlight

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

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

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

8 个答案:

答案 0 :(得分:28)

您无法绑定到标头,因为它不是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>

答案 1 :(得分: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}}" />

答案 2 :(得分:11)

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

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

答案 3 :(得分: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

答案 4 :(得分:2)

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

dg1.Columns[3].Header = SomeDynamicValue;

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

我提出的一点是,使用它更好 dg1.Columns[3].Header符号,而不是尝试引用命名列。

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

答案 5 :(得分:1)

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

dg1.Columns[3].Header = SomeDynamicValue;

答案 6 :(得分:1)

请注意RobSiklos提供的解决方案,Source {staticResource ...}是Key,如果您计划传递RelativeSource

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

它可能无法正常工作

答案 7 :(得分:0)

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

 HeaderTextBlock.SetBinding(TextBlock.TextProperty, HeaderBinding);

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