I am using a ScrollViewer as part of my Silverlight application. It has a horizontal orientation, and I would like it to appear such that only the scroll buttons appear, but not the scroll bar itself. Something like this crude ASCII rendering:
------------------------------------------------------
| | | |
| < | Content Here | > |
| | | |
------------------------------------------------------
I know I could use the templating functionality, but all the samples I've seen only change the look of all the elements, and not their raw positioning, or whether they even appear. Is it possible to do this, and could someone provide an outline of what the template might look like?
Here is another option. Override the default template for SCrollviewer and handle the buttons as PageUp/PageDown. My example below is a scrollviewer that scrolls vertically. You can easily change to to horizontal scrolling and change the handlers from PageUp/PageDown to Left and Right handlers.
<ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer">
<ControlTemplate.Resources>
<!-- Add style here for repeat button seen below -->
</ControlTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0"
Foreground="White"
Background="Yellow"
HorizontalAlignment="Stretch"
Command="ScrollBar.PageUpCommand"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}">
</RepeatButton>
<ScrollContentPresenter
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.Row="1"
Content="{TemplateBinding Content}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Margin="{TemplateBinding Margin}"/>
<RepeatButton Grid.Row="2" Background="Black" Foreground="White" Command="ScrollBar.PageDownCommand">
</RepeatButton>
</Grid>
</ControlTemplate>
I've done something similar and the best way I found to do this was to put your content in a scroll viewer and just turn off the scrollbars. Then code your buttons to scroll the scrollviewer.
Edit: Responding to comment about no way to deal with sizing.
First off, you would build this control as a ContentControl. It should have a template defined in generic.xaml that has your button controls plus the scroll viewer. Something like:
<Canvas x:Name="root">
<Button x:Name="left" Content="<"/>
<Button x:Name="right" Content=">"/>
<ScrollViewer x:Name="viewer" BorderThickness="0" VerticalScrollBarVisibility="Hidden">
<ContentPresenter />
</ScrollViewer>
</Canvas>
Then in your control you would need to override OnApplyTemplate:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
left = GetTemplateChild("left") as Button;
left.Click += new RoutedEvent(YourHandler);
right = GetTemplateChild("right") as Button;
right.Click += new RoutedEvent(YourHandler);
// position your scroll buttons here, not writing that code
scroll = GetTemplateChild("viewer") as ScrollViewer;
root = GetTemplateChild("root") as Canvas;
var fe = this.Content as FrameworkElement;
if (fe != null)
{
fe.SizeChanged += new SizeChangedEventHandler(fe_SizeChanged);
}
}
void fe_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.InvalidateMeasure();
}
protected override Size ArrangeOverride(Size finalSize)
{
if (!double.IsInfinity(scroll.ViewportHeight))
{
left.Visibility = (scroll.HorizontalOffset > 0);
right.Visibility = (scroll.HorizontalOffset < ScrollableHeight);
}
return base.ArrangeOverride(finalSize);
}
protected override Size MeasureOverride(Size availableSize)
{
scroll.Measure(availableSize);
return scroll.DesiredSize;
}
In your button click handlers you would need to (1) scroll the viewer and (2) check the new value of the HorizontalOffset to see if you need to hide or show either of the button.
Disclaimer: This code probably doesn't work as is since it was written by hand and based on a different example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With