开发者

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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜