Search code examples
wpfxaml

WPF xaml scroll Datagrid content and keep headers fixed


I am scrolling the entire Datagrid, including headers, as follows. However, I am not able to find a way to keep the column headers aside of the scrolling and let them fixed. How to reach it?

        <Grid Name="rowRecs0" Grid.Row="0">

            <ScrollViewer Height="200" VerticalScrollBarVisibility="Auto">

                <StackPanel>
                    <DataGrid
                        x:Name="datagridRecipes"
                        VerticalAlignment="Top"
                        AutoGenerateColumns="False"
                        CanUserAddRows="False"
                        CanUserReorderColumns="False"
                        CanUserResizeColumns="False"
                        CanUserResizeRows="False"
                        CanUserSortColumns="False"
                        IsReadOnly="True"
                        ItemsSource="{Binding UsersItems}"
                        SelectedIndex="{Binding UserSelectedIndex}"
                        SelectedItem="{Binding UserSelectedItem}"
                        SelectionChanged="datagridRecipes_SelectionChanged">


                        <DataGrid.Columns>

                            <materialDesign:DataGridTextColumn
                                Width="*"
                                EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"
                                Header="NAME">
                                <materialDesign:DataGridTextColumn.ElementStyle>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="VerticalAlignment" Value="Center" />
                                        <Setter Property="Height" Value="30" />
                                    </Style>
                                </materialDesign:DataGridTextColumn.ElementStyle>

                                <materialDesign:DataGridTextColumn.Binding>
                                    <Binding Path="RecipeName" />
                                </materialDesign:DataGridTextColumn.Binding>
                            </materialDesign:DataGridTextColumn>

                        </DataGrid.Columns>
                    </DataGrid>

                </StackPanel>

            </ScrollViewer>
        </Grid>

Solution

  • The DataGrid already has built-in row scrolling that does not affect the Column headers (and the row headers too). You just need to remove your Grid, ScrollViewer and StackPanel from your layout XAML. After that everything will work as it should.
    Corrected XAML of layout:

    <!--<Grid Name="rowRecs0" Grid.Row="0">
    <ScrollViewer Height="200" VerticalScrollBarVisibility="Auto">
    <StackPanel>-->
        <DataGrid Height="200"
            x:Name="datagridRecipes"
            VerticalAlignment="Top"
            AutoGenerateColumns="False"
            CanUserAddRows="False"
            CanUserReorderColumns="False"
            CanUserResizeColumns="False"
            CanUserResizeRows="False"
            CanUserSortColumns="False"
            IsReadOnly="True"
            ItemsSource="{Binding UsersItems}"
            SelectedIndex="{Binding UserSelectedIndex}"
            SelectedItem="{Binding UserSelectedItem}"
            SelectionChanged="datagridRecipes_SelectionChanged">
    
            <DataGrid.Columns>
                <materialDesign:DataGridTextColumn
                    Width="*"
                    EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"
                    Header="NAME">
                    <materialDesign:DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="VerticalAlignment" Value="Center" />
                            <Setter Property="Height" Value="30" />
                        </Style>
                    </materialDesign:DataGridTextColumn.ElementStyle>
    
                    <materialDesign:DataGridTextColumn.Binding>
                        <Binding Path="RecipeName" />
                    </materialDesign:DataGridTextColumn.Binding>
                </materialDesign:DataGridTextColumn>
    
            </DataGrid.Columns>
        </DataGrid>
    
    <!--</StackPanel>
    </ScrollViewer>
    </Grid>-->