ScrollViewer with non scrolling area (fixed header)
-
Wednesday, September 13, 2006 11:19 AM
How can I have a ScrollViewer with a fixed header (like the Column headers in a GridView).
<
ScrollViewer>
<StackPanel>
<Label Content="Header" />
...Some content...
</StackPanel>
</ScrollViewer>Best regards,
Thomas Andersen
All Replies
-
Wednesday, September 13, 2006 12:10 PMYou can retrofit HeaderedContentControl to meet your own needs:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
><Page.Resources>
<ControlTemplate TargetType="HeaderedContentControl" x:Key="myControlTemplate">
<StackPanel>
<ContentPresenter
ContentSource="Header"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
Content="{TemplateBinding HeaderedContentControl.Header}"/>
<ScrollViewer ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
Content="{TemplateBinding ContentControl.Content}"/>
</StackPanel>
</ControlTemplate>
</Page.Resources>
<HeaderedContentControl Header="HeaderText" Template="{StaticResource myControlTemplate}">
<!--Put your content here-->
</HeaderedContentControl>
</Page>
Sheva -
Wednesday, September 13, 2006 2:25 PM
Thanks.
Actually I forgot to mention an important part: The header is a GridViewHeaderRowPresenter witch I want to follow the horizontal scrolling?
Best regards,
Thomas Andersen -
Wednesday, December 20, 2006 10:57 AM
Thought I would post a solution - as this prooved a little problematic and noone else seemed to have a solution posted anywhere.
The trick is (maybe there are better solutions too) to wrap the header and content in a scrollviewer to allow horizontal scrolling and then to wrap the content items in a scrollviewer to allow vertical scrolling of the items.
The sample XAML below is for the TreeListView sample in MSDN.
The problem still remains that the inner scrollviewer can create a vertical scrollbar off-screen - whereas it would be nice to have it right-docked.
<
Style TargetType="{x:Type l:TreeListView}"><
Setter Property="OverridesDefaultStyle" Value="True" /><
Setter Property="Template"><
Setter.Value><
ControlTemplate TargetType="{x:Type l:TreeListView}"><
Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"><
DockPanel Dock="Top" HorizontalAlignment="Stretch"><
ScrollViewer Focusable="False" CanContentScroll="False" Padding="4" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"><
DockPanel Dock="Top" VerticalAlignment="Stretch"><
GridViewHeaderRowPresenter Columns="{StaticResource gvcc}" ColumnHeaderContainerStyle="{StaticResource driverRowHeaderStyle}" DockPanel.Dock="Top"></
GridViewHeaderRowPresenter><
ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" Focusable="False" VerticalAlignment="Stretch" CanContentScroll="False" Padding="4"><
ItemsPresenter VerticalAlignment="Stretch"/></
ScrollViewer></
DockPanel></
ScrollViewer></
DockPanel></
Border></
ControlTemplate></
Setter.Value></
Setter></
Style> -
Wednesday, November 18, 2009 5:15 PMDoes anyone know how to solve the vertical scrollbar off-screen problem?
-
Tuesday, March 08, 2011 1:34 PM
To solve the vertical scrollbar off-screen problem, use two ScrollView instances. Put the GridViewHeaderRowPresenter in its own ScrollView with hidden scrollbars. Put the ItemsPresenter in a second ScrollView with both scrollbars enabled. When the second ScrollView ScrollChanged event is fired, set the first ScrollView horizontal offset to match.
<Style TargetType="{x:Type l:TreeListView}"> <Setter Property="OverridesDefaultStyle" Value="True" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type l:TreeListView}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <DockPanel Dock="Top" HorizontalAlignment="Stretch"> <DockPanel Dock="Top" VerticalAlignment="Stretch"> <ScrollViewer Name="ScrollViewer_Header" DockPanel.Dock="Top" HorizontalAlignment="Left" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"> <GridViewHeaderRowPresenter Columns="{StaticResource gvcc}" ColumnHeaderContainerStyle="{StaticResource driverRowHeaderStyle}"/> </ScrollViewer> <ScrollViewer Name="ScrollViewer_Body" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <ItemsPresenter/> </ScrollViewer> </DockPanel> </DockPanel> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
class TreeListView : TreeView { ScrollViewer ScrollViewer_Header; ScrollViewer ScrollViewer_Body; public override void OnApplyTemplate() { base.OnApplyTemplate(); this.ScrollViewer_Header = (ScrollViewer)this.Template.FindName("ScrollViewer_Header", this); this.ScrollViewer_Body = (ScrollViewer)this.Template.FindName("ScrollViewer_Body", this); this.ScrollViewer_Body.ScrollChanged += new ScrollChangedEventHandler(ScrollViewer_Body_ScrollChanged); } void ScrollViewer_Body_ScrollChanged(object sender, ScrollChangedEventArgs e) { this.ScrollViewer_Header.Width = e.ViewportWidth; this.ScrollViewer_Header.ScrollToHorizontalOffset(e.HorizontalOffset); } }
- Proposed As Answer by LeeCampbell Wednesday, March 07, 2012 4:44 PM
-
Wednesday, March 07, 2012 4:46 PM
Cheers Ian,
I was banging my head on that one for a while trying to use only Binding. The private setters make that impossible however. Your ScrollToHorizontalOffset(e.HorizontalOffset); worked a treat. Thanks.
Lee Campbell http://LeeCampbell.blogspot.com

