Search This Blog

Friday, February 3, 2012

Silverlight sdk:DataGrid Column Header DataBinding; How to set DataBinding in Column Header in Silverlight

There is a problem with setting DataBinding as a Header in Column (e.g. DataGridTextColumn) from Silverlight Client SDK. Unfortunately Header is not a dependency property, do binding to it will result in converting DataBinding to string (calling its ToString() method).

“System.Windows.Data.Binding”

To overcome the problem create a helper with a Dependency property (e.g. HeaderBinding). Change to HeaderBinding binding should set the real Header string.

Usage:

<sdk:DataGridTextColumn Controls:DataGridColumnHelper.HeaderBinding="{Binding Something” />

 

Helper:

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

11 comments:

  1. Hi, I would like to implement this code but I don't have any idea where the helper should be implemented.
    Please give me a little more information about it.
    Thanks.

    ReplyDelete
  2. I didn't work for me.. :(

    ReplyDelete
  3. @Anonymous
    "I don't have any idea where the helper should be implemented. "

    Hi.
    The code actually can be implemented anywhere as it is a static class. You just copy&paste the code for "public static class DataGridColumnHelper".
    Then you reference this class in xaml where you have your DataGrid. When you create columns (sdk:DataGridTextColumn) instead of writing:

    <sdk:DataGridTextColumn Header="{Binding someProp}" />

    which wouldn't work as there would an error: "cannot convert System.Binding to System.String"

    so you write:

    <sdk:DataGridTextColumn Controls:DataGridColumnHelper.HeaderBinding="{Binding Something” />

    and the static class (in particular its dependency property HeaderBinding) writes the data to the header for you.
    So you write the data to DataGridColumnHelper.HeaderBinding and this class writes it to the sdk:DataGridTextColumn.Header for you automatically.

    Thanks for the comment.

    ReplyDelete
    Replies
    1. Hi thanks for your help, but I'm still in problems with the header binding. I implemented the class, this is it.

      public static class DataGridColumnHelper
      {
      public static readonly DependencyProperty HeaderBindingProperty = DependencyProperty.RegisterAttached(
      "HeaderBinding",
      typeof(string),
      typeof(DataGridColumnHelper),
      new PropertyMetadata(null, DataGridColumnHelper.OnHeaderBindingPropertyChanged));
      public static void SetHeaderBinding(DependencyObject dp, string value)
      {
      dp.SetValue(HeaderBindingProperty, value);
      }

      public static string GetHeaderBinding(DependencyObject dp)
      {
      return (string)dp.GetValue(HeaderBindingProperty);
      }

      private static void OnHeaderBindingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
      DataGridColumn column = sender as DataGridColumn;
      if (column == null) { return; }
      column.Header = e.NewValue;
      }

      }

      }
      and in the xaml code I added the property like this:



      I don't have any mistake in compilation but when I excecute the application, the header appears empty.

      I don't know where is the problem.
      I'll be grateful if you can help me.

      Thanks.

      Delete
  4. Good solution! Works well for me..

    Thanks!
    Julio

    ReplyDelete
  5. Hello, can you please attach to the post some sample project. I can't make your example work. I had investigate, that DataGridColumn is not part of VisualTree. So I'm curious how you made it works.

    ReplyDelete
  6. Great code! Works in XAML but I have not been able to make it work in code behind. I have to create a dynamic child datagrid withing another datagrid and the column headers need to be bound to localized strings using a custom resources wrapper.

    The XAML that worked was:

    DataGridColumnHelper.HeaderBinding="{Binding Source={StaticResource LocTranslation}, Path=LocalizedStrings.Title}"

    The code behind that I tried was:

    var b = new Binding();
    b.Source = new Helpers.CustomResources();
    b.Path = new PropertyPath("LocalizedStrings.Title");
    b.Mode = BindingMode.OneWay;
    DataGridColumnHelper.SetHeaderBinding(column, b);

    The result is the all to familiar "System.Windows.Data.Binding" instead of the desired binding value.

    Do you have any idea how to get this to work? Thanks.

    ReplyDelete
  7. This only seems to work when you are attaching to a static/local resource. if you are trying to bind to something in your datacontext it doesn't appear to work.

    ReplyDelete
  8. Greatttttttttttttttttttt !
    Thanks !!!!!!!!

    ReplyDelete
  9. i am return List<> from the web services and bind that with Data Grid View. And data grid view property is autocolumncreated = true. But i want to change my column name how?

    ReplyDelete
  10. how add 'Contols' , we need to define any xmlns ?
    <sdk:DataGridTextColumn Controls:DataGridColumnHelper.HeaderBinding="
    {Binding Something” />

    ReplyDelete

If you like this post, please leave a comment :)