mobearette
mobearette

Reputation: 397

Applying The Same Height For All DataGridColumns when MaxWidth of the Header Is Set

I have an ItemsControl containing dynamically changable number of DataGrids:

<ItemsControl ItemsSource="{Binding Table.Columns}">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"/>
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>

   <ItemsControl.ItemTemplateSelector>
      <local:ColumnTemplateSelector InputParameterColumnTemplate="{StaticResource InputParamterColumn}"
                                    SingleParameterColumnTemplate="{StaticResource SingleParameterColumn}"/>
   </ItemsControl.ItemTemplateSelector>
</ItemsControl>

The template for the "SingleParameterColumn" is defined like this:

    <DataTemplate x:Key="SingleParameterColumn">       
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Cells}"      
                                   RowHeight="25" RowHeaderWidth="0" >
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}"
                                           TextWrapping="Wrap"
                                           TextAlignment="Center"
                                           MaxWidth="60">
                                </TextBlock>
                                <Button>
                                    <Image ... />
                                </Button>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.CellTemplateSelector>....
                    </DataGridTemplateColumn.CellTemplateSelector>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </DataTemplate>

There is always one InputParameterColumn and at least one SingleParameterColumn. The InputParameterColumn has a fixed header name, whereas the header of the SingleParameterColumn can be arbitrarily long.

Since I do not want to have very wide columns I have defined the MaxWidth of the TextBlock in the header template to 60, which causes the header to be higher if the name of a column is very long.

This causes the columns to have different heights depending on the length of the header name. Here is the issue:

Is there any way I can find out how tall is the tallest header in my ItemsControl and then set the same height for all the other headers so that my columns then all have the same size?

Upvotes: 9

Views: 1320

Answers (2)

almulo
almulo

Reputation: 4978

I could finally reproduce your problem, and managed to solve it with these changes:

  1. Set Grid.IsSharedSizeScope="True" on the StackPanel that serves as ItemsPanel for your ItemsControl
  2. On you ItemTemplate, Change the StackPanels of the HeaderTemplates for Grids
  3. On each Grid, define a single row with the same SharedSizeGroup identifier

ItemsControl:

<ItemsControl ItemsSource="{Binding Table.Columns}">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"
                     Grid.IsSharedSizeScope="True" />
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>

   <ItemsControl.ItemTemplateSelector>
      <local:ColumnTemplateSelector InputParameterColumnTemplate="{StaticResource InputParamterColumn}"
                                    SingleParameterColumnTemplate="{StaticResource SingleParameterColumn}"/>
   </ItemsControl.ItemTemplateSelector>
</ItemsControl>

ItemTemplate:

<DataTemplate x:Key="SingleParameterColumn">       
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Cells}"      
              RowHeight="25" RowHeaderWidth="0">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"
                                               SharedSizeGroup="DataGridHeaderRow" />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding Name}"
                                       TextWrapping="Wrap"
                                       TextAlignment="Center"
                                       MaxWidth="60">
                            </TextBlock>
                            <Button Grid.Column="1">
                                <Image ... />
                            </Button>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.HeaderTemplate>
                <DataGridTemplateColumn.CellTemplateSelector>....
                </DataGridTemplateColumn.CellTemplateSelector>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</DataTemplate>

Upvotes: 9

Tam&#225;s Deme
Tam&#225;s Deme

Reputation: 2228

You could write a behavior that attaches to the header TextBlock, and does the following:

  • subscribe to the SizeChanged event
  • store somewhere (static prop or helper class...) the largest size
  • if this largest size changes, just change the height of all elements the behavior is attached to

Upvotes: 0

Related Questions