Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF GridView header does not scroll horizontally

I have a GridView with a ScrollViewer that used to scroll horizontally along with the content of the GridView. I changed it using Chris Cavanagh's rounded corners solution, which includes putting a grid around the GridViewHeaderRowPresenter and adding a border to the same level which is then used as an opacity mask (see this question for more information).

This seems to disable horizontal scrolling for the header. If I resize the browser window to something smaller forcing a scrollbar for the content, the header stays fixed. I imagine that the added xaml somehow disables scrolling for the header.

This is what the code currently looks like. Please note that this is in a style definition that targets a ScrollViewer element, not directly in the XAML markup on the page.

<ScrollViewer Focusable="false"
              HorizontalScrollBarVisibility="Hidden"
              VerticalScrollBarVisibility="Hidden"
              DockPanel.Dock="Top"
              Style="{DynamicResource HEK_ScrollViewer}">
    <Grid>
        <Border Name="Mask"
                CornerRadius="20,20,0,0"
                Background="White" />
        <GridViewHeaderRowPresenter Margin="1,0,1,1"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    Columns="{Binding TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
                                    AllowsColumnReorder="{Binding TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderContainerStyle="{DynamicResource HEK-GridViewColumnHeaderStyle}"
                                    ColumnHeaderContextMenu="{Binding TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderStringFormat="{Binding TemplatedParent.View.ColumnHeaderStringFormat, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderTemplate="{Binding TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderTemplateSelector="{Binding TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
                                    ColumnHeaderToolTip="{Binding TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}">
            <GridViewHeaderRowPresenter.OpacityMask>
                <VisualBrush Visual="{Binding ElementName=Mask}" />
            </GridViewHeaderRowPresenter.OpacityMask>
        </GridViewHeaderRowPresenter>
    </Grid>
</ScrollViewer>
like image 888
Anne Schuessler Avatar asked Nov 10 '10 13:11

Anne Schuessler


2 Answers

I'm not really sure what is causing that behavior. I'm guessing there's some code in the ListView that expects a GridViewHeaderRowPresenter as a direct child of the header ScrollViewer.

But if you move up the grid as parent to the ScrollViewer, it scrolls correctly.

<DockPanel Margin="{TemplateBinding Padding}">
    <Grid DockPanel.Dock="Top">
        <Border Name="Mask" CornerRadius="4,4,0,0" Background="White" />
        <ScrollViewer  Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
            <GridViewHeaderRowPresenter  AllowsColumnReorder="{Binding TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContainerStyle="{Binding TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderToolTip="{Binding TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContextMenu="{Binding TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderTemplate="{Binding TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}" Columns="{Binding TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}" Margin="2,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                <GridViewHeaderRowPresenter.OpacityMask>
                    <VisualBrush Visual="{Binding ElementName=Mask}" />
                </GridViewHeaderRowPresenter.OpacityMask>
            </GridViewHeaderRowPresenter>
        </ScrollViewer>
    </Grid>
    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" KeyboardNavigation.DirectionalNavigation="Local" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</DockPanel>
like image 139
Tedy Pranolo Avatar answered Nov 04 '22 08:11

Tedy Pranolo


GridViewHeaderRowPresenter needs ScrollViewer as a parent, it's hardcode. You can change its template

Example:

<ScrollViewer.Template>
  <ControlTemplate TargetType="{x:Type ScrollViewer}">
    <Grid x:Name="Grid" Background="{TemplateBinding Background}">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
      </Grid.RowDefinitions>
        <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0">
          <ScrollContentPresenter.ContentTemplate>
            <DataTemplate>
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="25"/>
                  <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Border BorderBrush="Gray" BorderThickness="0,0,1,1">
                </Border>
                <ContentPresenter Grid.Column="1" Content="{TemplateBinding Content}"/>
              </Grid>
            </DataTemplate>
          </ScrollContentPresenter.ContentTemplate>
        </ScrollContentPresenter>
      <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
      <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
    </Grid>
  </ControlTemplate>
</ScrollViewer.Template>
like image 39
Mykhailo Pantia Avatar answered Nov 04 '22 06:11

Mykhailo Pantia