wpf 如何在dataGrid中更改滚动条位置

enyaitl3  于 2023-03-31  发布在  其他
关注(0)|答案(1)|浏览(601)

我设置了FrozenColumnCount=‘2’,HorizontalScrollBar将在最后一列冻结后显示,但我希望滚动条正常显示。
守则:

public class MyDataGrid:DataGrid
    {
        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            var scrollBar = VisualTreeHelpers.GetChildObject(this, "PART_HorizontalScrollBar") as ScrollBar;
            var parentGrid = VisualTreeHelpers.FindVisualParentOfType<Grid>(scrollBar); 
            var size = base.ArrangeOverride(arrangeBounds);
            
            scrollBar.Arrange(new Rect(new Point(0,0),new Size(parentGrid.RenderSize.Width,scrollBar.DesiredSize.Height)));
            return size;
        }
    }

xaml:

<local:MyDataGrid ItemsSource="{Binding List}" Loaded="FrameworkElement_OnLoaded" >
        <DataGrid.FrozenColumnCount>2</DataGrid.FrozenColumnCount>
       <DataGrid.Columns>
            <DataGridTextColumn Header="col1"></DataGridTextColumn>
            <DataGridTextColumn Header="col2"></DataGridTextColumn>
            <DataGridTextColumn Header="col3"></DataGridTextColumn>
            <DataGridTextColumn Header="col4"></DataGridTextColumn>
            <DataGridTextColumn Header="col5"></DataGridTextColumn>
            <DataGridTextColumn Header="col6"></DataGridTextColumn>
        </DataGrid.Columns>
   </local:MyDataGrid>

我试着调用scrollBar.InvalidateArrange(),但它也不起作用。当我调整窗口大小时,滚动条将显示预期。

vfh0ocws

vfh0ocws1#

要修改控件的布局,通常必须覆盖默认的ControlTemplate。在这种情况下,必须显式地告诉水平滚动条跨越宿主Grid的两列(冻结列和非冻结列)。
以下调整基于Microsoft Docs上找到的DataGrid的默认Style:DataGrid ControlTemplate示例。Style应该类似于使用Blend或Visual Studio提取默认控件Style时获得的样式。
ControlTemplate包含一个ScrollViewer。为了排除冻结的列,修改了此ScrollViewer的模板。
为了实现这一点,将水平ScrollBar添加到定义两列的Grid:第一个用作冻结列的占位符,第二个用于托管ScrollBar
要实现所需的布局,只需允许滚动条跨越两列:

<ScrollViewer.Template>
  <ControlTemplate TargetType="{x:Type ScrollViewer}">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>

      ...

      <Grid Grid.Column="1"
            Grid.Row="2">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
          <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <!-- Allow the ScrollBar to span across both columns to include the frozen columns -->
        <ScrollBar x:Name="PART_HorizontalScrollBar"
                   Grid.Column="0" Grid.ColumnSpan="2"
                   Orientation="Horizontal"
                   ViewportSize="{TemplateBinding ViewportWidth}"
                   Maximum="{TemplateBinding ScrollableWidth}"
                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                   Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
      </Grid>
    </Grid>
  </ControlTemplate>
</ScrollViewer.Template>

相关问题