SHIFT + 滚动可在 ScrollViewer UWP 中水平滚动

Mic*_*hem 4 c# xaml event-handling scrollviewer uwp

我想在滚动时按住键盘上的 SHIFT 来ScrollViewer水平滚动。

我从这里了解到,该PointerWheelChanged活动就是我正在寻找的活动。然而,处理它是行不通的,因为它是ScrollViewer在内部处理的,所以我的处理程序永远不会被调用。为了解决这个问题,我使用了“路由事件概述”AddHandler一文中所述的方法。

这有效......但似乎在运行ScrollViewer其内部代码后运行我的代码。其结果是ScrollViewer内容先垂直平移,然后水平平移。它们似乎按照这个顺序发生,并且设置e.Handled = true并不能阻止它。

有没有办法“拦截”滚动,以便我可以用自己的逻辑处理它,从而允许在ScrollViewer按下 SHIFT 时水平平移?我最近在这里问了一个类似的问题(涉及拦截控件的输入,以便我可以用自己的逻辑处理它),其中答案涉及处理不同的事件,该事件发生在控件运行其自己的逻辑之前。我没有看到指针滚动的类似“发生前的事情”事件。

我的代码如下。请注意,ScrollViewer可以水平和垂直滚动以及缩放:

<!-- Contained in Grid in a UserControl, if that's relevant -->
<ScrollViewer Name="MyCanvasScrollViewer"
              VerticalScrollBarVisibility="Auto"
              HorizontalScrollBarVisibility="Auto"
              ZoomMode="Enabled"
              ZoomSnapPointsType="Optional"
              PointerWheelChanged="MyCanvasScrollViewer_PointerWheelChanged">
    <!-- Content to pan -->
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

隐藏代码:

// Constructor for the user contol.
public MyControl()
{
    // Add the scroll wheel event handler and force it to run.
    this.MyCanvasScrollViewer.AddHandler(ScrollViewer.PointerWheelChangedEvent, new PointerEventHandler(this.MyCanvasScrollViewer_PointerWheelChanged), true);

    // Other un-related stuff omitted here...
}

// Event handler for the Pointer Wheel Changed event.
private void MyCanvasScrollViewer_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
    // If SHIFT is pressed...
    var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
    if ((keyState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
    {
        // Get the amount to scroll.
        PointerPoint pointer = e.GetCurrentPoint(this.WallCanvasScrollViewer);
        double scrollWheelDelta = pointer.Properties.MouseWheelDelta;

        // Change the view in the scroll viewer.
        this.MyCanvasScrollViewer.ChangeView(scrollWheelDelta, null, null, true);

        // Mark event as handled.
        e.Handled = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Vig*_*esh 5

您可以简单地VerticalScrollModeshift keydown中禁用它并在keyup上启用它。本身不需要pointerwheelchanged。它工作得很好。

沙姆尔

<ScrollViewer ZoomMode="Enabled" x:Name="MyScrollViewer"  HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible" >
   <Image Height="600" Width="500" Source="/Assets/1.jpg"></Image>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

//C#代码

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        CoreWindow.GetForCurrentThread().KeyDown += MainPage_KeyDown;
        CoreWindow.GetForCurrentThread().KeyUp += MainPage_KeyUp; ;
    }

    private void MainPage_KeyUp(CoreWindow sender, KeyEventArgs args)
    {
        if (args.VirtualKey == VirtualKey.Shift)
        {                
            MyScrollViewer.IsScrollInertiaEnabled = true;
            MyScrollViewer.VerticalScrollMode = ScrollMode.Enabled;
        }
    }

    private void MainPage_KeyDown(CoreWindow sender, KeyEventArgs args)
    {
        if (args.VirtualKey == VirtualKey.Shift)
        {
            MyScrollViewer.IsScrollInertiaEnabled = false;
            MyScrollViewer.VerticalScrollMode = ScrollMode.Disabled;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 设置 MyScrollViewer.IsScrollInertiaEnabled = false; 按下键并启用它。让跳跃停止。我已经编辑了我的答案 (3认同)
  • 这似乎大部分有效。我的“ScrollViewer”中的内容在 X 和 Y 方向上都大得多。虽然按住 SHIFT 确实允许水平滚动,但“ScrollViewer”在水平滚动之前首先跳转到特定的垂直滚动值...无论我的垂直方向是什么值是我开始水平滚动时的值。想法? (2认同)