5

I have a listview which is binded to source. It is working fine. I have set ScrollViewer.VerticalScrollBarVisibility="Auto", so that if there is no space to show the items, it should display the scroll bar.

Upto this it is working fine. It is showing the vertical scroll bar, but it is including the header of GridViewColoumn also. It is looking odd.

So how to show the vertical scrollbar only for the contents, not with header?

Any idea will be helpful.

2
  • Do you mean that you don't want the scrollbar to overlap the header row? Commented Dec 28, 2011 at 9:40
  • @snurre Yes, the vertical scroll bar includes the Header row also Commented Dec 28, 2011 at 9:45

2 Answers 2

5

Try this...

        <ListView.Resources>
            <Style TargetType="{x:Type ScrollBar}"
                   BasedOn="{StaticResource {x:Type ScrollBar}}">
                <Style.Triggers>
                    <Trigger Property="Name" Value="PART_VerticalScrollBar">
                        <Setter Property="Margin" Value="0,18,0,0"/>
                    </Trigger>
                </Style.Triggers>                   
            </Style>
        </ListView.Resources>

EDIT:

To understand how this works first you will have to refer this msdn article that gives you the default template of the list view ... http://www.google.co.in/url?q=http://msdn.microsoft.com/en-us/library/ms788747(v%3Dvs.85).aspx&sa=U&ei=r_L6TuXlJ8XyrQep_anODw&ved=0CBQQFjAC&sig2=HNWppacyWyhYxn2NcUSbEw&usg=AFQjCNHzlst2jA_pMTzZsUGNxtbWBqYQLQ

In this template we have the verticle scroll bar defined with name PART_VerticalScrollBar.

Now if you want to change its properties such as Margin, you will have to set a default target type style for the scroll bar. In our example above, the targetType of the style is Scrollbar class but it has no resource Key! This means all scroll bars under that ListView will acquire the style and set their top margin to 18px. But we dont want it to apply to all scroll bars so I added a trigger that only targets this style to scrollbar with name "PART_VerticalScrollBar".

Let me know if this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it is working fine. I have changed the margin. But could you pls explain how it is working?
3

I would achieve this by overriding the style for the ScrollViewer. The benefit of this is that it handles header resizing automatically.

XAML:

<Grid>
  <Grid.Resources>
    <local:HeightToMarginConverter x:Key="HeightToMarginConverter"/>
    <Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="{x:Type ScrollViewer}">
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                    <Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
<!-- Here I set Grid.ColumnSpan to 2, so it stretches over the scrollbar -->
                        <DockPanel Margin="{TemplateBinding Padding}" Grid.ColumnSpan="2">
                            <ScrollViewer DockPanel.Dock="Top" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
                                <GridViewHeaderRowPresenter x:Name="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}}" ColumnHeaderStringFormat="{Binding TemplatedParent.View.ColumnHeaderStringFormat, 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}}" ColumnHeaderTemplateSelector="{Binding TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}" Margin="2,0,2,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </ScrollViewer>
                            <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" KeyboardNavigation.DirectionalNavigation="Local" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </DockPanel>
                        <ScrollBar x:Name="PART_HorizontalScrollBar" Cursor="Arrow" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0.0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
<!-- Here I set the vertical scrollbar's top margin by binding it to the GridViewHeaderRowPresenter's ActualHeight property and using a converter -->
                        <ScrollBar x:Name="PART_VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0.0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Margin="{Binding ActualHeight, ElementName=gridViewHeaderRowPresenter, Converter={StaticResource HeightToMarginConverter}}"/>
                        <DockPanel Background="{Binding Background, ElementName=PART_VerticalScrollBar}" Grid.Column="1" LastChildFill="false" Grid.Row="1">
                            <Rectangle DockPanel.Dock="Left" Fill="White" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Width="1"/>
                            <Rectangle DockPanel.Dock="Top" Fill="White" Height="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                        </DockPanel>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  </Grid.Resources>
  <ListView>
    <!-- Normal stuff here -->
  </ListView>
</Grid>

HeightToMarginConverter.cs:

class HeightToMarginConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? new Thickness() : new Thickness(0, (double)value, 0, 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.