0

I am using a DataGrid with AutogenerateColumns set to true.

I'm binding it to a weakly-typed DataTable via its DataContext property.

The problem I've run into is that all the headers must have unique names, because myGrid.Columns[x].Header value is tied directly to the column name of the underlying DataTable (where, obviously, no duplicate column names are allowed).

Is there any sensible workaround?

Konrad Morawski
  • 8,307
  • 7
  • 53
  • 91
  • Can you please elaborate more on your problem? Isnt DataTable doing what you want (uniqueness of column names) right? – WPF-it Aug 03 '11 at 15:03
  • I want to have non-unique headers in the `DataGrid` - display names; in UI! Without affecting column names in the `DataTable` (which causes an exception to be thrown). I don't want the (visible) header names to be connected with (logical) column names at all; but as of now, they are. – Konrad Morawski Aug 03 '11 at 15:07

1 Answers1

1

Following code is untested...

For DataGridHeaders to be changed, you would have to override their ContentTemplate.

    <DataGrid.Resources>   
     <Style TargetType="{x:Type dg:DataGridColumnHeader}">
      <Setter Property="ContentTemplate">
         <Setter.Value>
            <DataTemplate>
               <StackPanel>
                   <TextBlock>
                      <TextBlock.Text>
                          <MultiBinding Converter="{StaticResource DynamicColumnHeaderTextConverter}">
                               <Binding BindsDirectlyToSource="True"/>
                               <Binding Path="ItemsSource" RelativeSource="{RelativeSource AncestorType={x:Type dg:DataGrid}}" />
                          </MultiBinding>
                      </TextBlock.Text>
                   </TextBlock> 
               </StackPanel>
           </DataTemplate>
         </Setter.Value>
      </Setter>
     </Style>
    </DataGrid.Resources>

In the above code DynamicColumnHeaderTextConverter's Convert() method will receive 2 values

  1. Column Header i.e. DataTable Column Name
  2. DataTable itself.

Based on this return the non-unique names.

    public class DynamicColumnHeaderTextConverter : IMultiValueConverter
    {
         public object Convert(object[] values, ...)
         {
              var columnName = (string)values[0];
              var dataTable = (DataTable)values[1]; //// if you want to decide name based on some value in the DataTable.
              switch(columnName)
              {
                   case "MyColumn1" : return "MyColumn";
                   case "MyColumn2" : return "MyColumn";
              }

              return columnName; 
         }
    }

Let me know if this helps.

WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • Thanks! I'll try this tomorrow (I'm nearly done for today :)). Btw I've already overriden `DataGridColumnHeader` `ContentTemplate`, so I'll just incorporate the code you proposed. I will let you know – Konrad Morawski Aug 03 '11 at 15:41
  • I tried that, but no unfortunately it doesn't work. I'm getting a XamlParseException: "A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject." – Konrad Morawski Aug 03 '11 at 16:15
  • Hey Vibo, sorry for the code mistake... should be ... I have edited my code above... sorry for the trouble again! – WPF-it Aug 03 '11 at 18:03
  • Thank you - but it doesn't work either. I created a small project out of your updated sample code at home now, and I got the same exception again: A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. – Konrad Morawski Aug 03 '11 at 19:34
  • I'm sure I'm doing something wrong, but I have no clue what it is. I'll keep on trying still. – Konrad Morawski Aug 03 '11 at 19:39
  • Actually my mistake again... :) the second binding is wrong tooo... ... it must work now :-) – WPF-it Aug 04 '11 at 05:40
  • Yeah, great! Thanks for help. I have to say WPF is really baffling – Konrad Morawski Aug 05 '11 at 12:10