Is it possible to implement a "slide-to-scroll" behaviour for ScrollViewer?
For a touchscreen-enabled application, I would like to modify the standard ScrollViewer controls in my WPF 3.5 application: Instead of showing scrollbars, I want the user to scroll by clicking in the control area and dragging the content (similar to the behaviour on Apple's iPhone). I would like to do that by applying a style to the ScrollViewer, because (a) I can apply a style automatically to an开发者_如何学Goy ScrollViewer in a window (even the ones contained in controls like ListView) and (b) I can use the standard Windows Scrollbar-style if the application is running on a normal desktop with keyboard and mouse.
My first idea was to use a custom control template for the ScrollViewer. The default control template is described in the MSDN and uses a ScrollContentPresenter. Normally, I would just derive a class from ScrollContentPresenter and add the slide-to-scroll behaviour there, but for some reason, ScrollContentPresenter is sealed - I can't derive from it. I've tried putting a ScrollContentPresenter into a UserControl, and putting the user control into the ScrollViewer control template, but that didn't work either.
Is there a simple way to get this behaviour, without re-writing all the ScollViewer/ScrollContentPresenter functionality?
Update
Made the ScrollBars Hidden and added MouseLeave to release the scrolling
A Slide ScrollViewer with a Rectangle inside
<Grid Width="500"
Height="250">
<ScrollViewer Name="slideScrollViewer"
Style="{StaticResource slideScrollViewer}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Rectangle Width="1000"
Height="500">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0.0" Color="Red"/>
<GradientStop Offset="0.33" Color="Green"/>
<GradientStop Offset="0.66" Color="Blue"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</ScrollViewer>
</Grid>
SlidingScrollViewer.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="StyleScrollViewer.SlidingScrollViewer">
<Style x:Key="slideScrollViewer" TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="VerticalScrollBarVisibility" Value="Hidden"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="slideScrollViewer_PreviewMouseLeftButtonDown"/>
<EventSetter Event="PreviewMouseLeftButtonUp" Handler="slideScrollViewer_PreviewMouseLeftButtonUp"/>
<EventSetter Event="MouseMove" Handler="slideScrollViewer_MouseMove"/>
<EventSetter Event="MouseLeave" Handler="slideScrollViewer_MouseLeave"/>
</Style>
</ResourceDictionary>
SlidingScrollViewer.xaml.cs
public partial class SlidingScrollViewer
{
private bool m_isCaptured = false;
Point m_lastCoordinate = new Point(-1, -1);
private void slideScrollViewer_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
m_isCaptured = true;
}
private void slideScrollViewer_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
m_isCaptured = false;
m_lastCoordinate.X = -1;
}
private void slideScrollViewer_MouseMove(object sender, MouseEventArgs e)
{
if (m_isCaptured == true)
{
ScrollViewer scrollViewer = sender as ScrollViewer;
Point coordinate = e.GetPosition(scrollViewer);
if (m_lastCoordinate.X >= 0)
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + (m_lastCoordinate.X - coordinate.X));
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + (m_lastCoordinate.Y - coordinate.Y));
}
m_lastCoordinate = coordinate;
}
}
private void slideScrollViewer_MouseLeave(object sender, MouseEventArgs e)
{
m_isCaptured = false;
m_lastCoordinate.X = -1;
}
}
精彩评论