Search code examples
c#wpfxamldatagrid

DataGrid Merging rowheaders


i am creating a timeplan with drag function and am using datagrids for their amazing data binding and cell selection functionality. all works well, except now i want to have the row headers (time) only show the hours and not the half hour segments.

This is what i want:

how i want it

And This is what i get: how it looks

Is there a way to merge the row headers without loosing the function of actual rows? I tried to just overlap the row header with another box, but this seems clunky


Solution

  • so i did the following: I created a grid on the side of the rowheaders, which i filled with half as many rows as the datagrid. the first row has a set height, so it matches the height of the Datagrid header, which i do not want to scale, as it contains the week day names

    <Grid x:Name="Grid_Datagrid_Times_box" 
                 Grid.Column="1"
                 Grid.Row="1"
                 Grid.RowSpan="2"
                 Grid.ColumnSpan="2"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch">
    
         <Grid.ColumnDefinitions>
               <ColumnDefinition Width="0.3*"/>
               <ColumnDefinition Width="8*"/>
         </Grid.ColumnDefinitions>
         <Grid x:Name="Grid_Times"
               Grid.Column="0">
    
               <Grid.RowDefinitions>
                      <RowDefinition Height="30"/>
               </Grid.RowDefinitions>
         </Grid>
         <DataGrid x:Name="DataGrid_Timetable"
                   Grid.Column="1"
                   VerticalAlignment="Stretch"
                   HorizontalAlignment="Stretch"
                   ColumnHeaderHeight="30">
          ...
        </DataGrid>
    

    in codebehind on Size Changed is set

    private void Datagrid_Resize(object sender, SizeChangedEventArgs e)
        {
            DataGrid DG = new DataGrid();
            if ((sender) is DataGrid)
            {
                DG = (DataGrid)sender;
            }
            double test = DG.RowHeight;
            DataGridRow rowt = GetFirstVisualChild<DataGridRow>(DG, 1);
            double testR = rowt.ActualHeight; 
    
    
            DG.RowHeight = (Grid_Datagrid_Times_box.ActualHeight-30) /    (numberOfRows);
            
            for (int i = 0; i < (numberOfRows+2); i++)
            {
                DataGridRow row = GetFirstVisualChild<DataGridRow>(DG, i);
                if (row != null)
                {
                    row.FontSize = DG.RowHeight / 2.3;
                    row.Height = DG.RowHeight;
                }
                foreach (UIElement ele in Grid_Times.Children)
                {
                    if (ele.GetType() == typeof(TextBlock))
                    {
                        TextBlock txtb = (TextBlock)ele;
                        txtb.FontSize = DG.RowHeight;
                    }
                }
              }
        }
    

    and

    public static T GetFirstVisualChild<T>(DependencyObject depObj, int index) where T : DependencyObject
        {
            if (depObj != null)
            {
                int counter = 0;
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T )
                    {
                        counter++;
                        if (counter==index)
                            return (T)child;
                    }
    
                    T childItem = GetFirstVisualChild<T>(child, index);
                    if (childItem != null) return childItem;
                }
            }
    
            return null;
        }