Datagrid 中的 C# WPF Expander 在滚动时应该被冻结(修复)

C# WPF Expander in Datagrid should be frozen (fix) while scrolling

我有一个带有 Expander 的数据网格,如下所示:

<DataGrid ItemsSource="{Binding}" Name="MainDataGrid" 
                                      AutoGenerateColumns="False"                   
                                      HorizontalAlignment="Stretch"
                                      VerticalAlignment="Stretch"    
                                      SelectionMode="Extended"
                                      CanUserDeleteRows="False" 
                                      CanUserAddRows="False" 
                                      SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                                      >
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander Background="#F0F7FC" BorderThickness="0" BorderBrush="BlanchedAlmond" >
                                        <Expander.Header>

                                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                                <TextBlock Text="Text"  />
                                            </StackPanel>
                                        </Expander.Header>
                                        <ItemsPresenter />
                                    </Expander >
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>

        </DataGrid.GroupStyle>
    </DataGrid>

数据网格有一个冻结列和一些可变列。当我垂直滚动时,扩展器 header 也会滚动并消失。有没有办法也冻结扩展器集线器?

滚动前的数据网格:

滚动后的数据网格(Expander header 滚开):

我找到了解决方法:

A Simple Workaround

The simplest workaround I thought of is to adjust the left margin of the header every time the DataGrid is scrolled horizontally. To do this, we can subscribe to the ScrollChanged event of the DataGrid’s ScrollViewer, get the group header and set its margin. In our example though, we used an Expander so we need to find the ToggleButton and set its left margin. The following code listing shows the event handler for the ScrollChanged event and a recursive method that searches for the ToggleButton using the VisualTreeHelper utility class.

private void DataGrid_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    var dataGrid = (DataGrid)sender;
    if (dataGrid.IsGrouping && e.HorizontalChange != 0.0)
    {
        TraverseVisualTree(dataGrid, e.HorizontalOffset);
    }
}

private void TraverseVisualTree(DependencyObject reference, double offset)
{
    var count = VisualTreeHelper.GetChildrenCount(reference);
    if (count == 0)
        return;

    for (int i = 0; i < count; i++)
    {
        var child = VisualTreeHelper.GetChild(reference, i);
        if (child is ToggleButton)
        {
            var toggle = (ToggleButton)child;
            toggle.Margin = new Thickness(offset, 0, 0, 0);
        }
        else
        {
            TraverseVisualTree(child, offset);
        }
    }
}

来源:http://www.nullskull.com/a/1509/freeze-row-group-header-in-wpf-datagrid.aspx

这不是完美的解决方案,但对于我的项目来说没问题!