C# 班次+;滚动以在ScrollViewer UWP中水平滚动

C# 班次+;滚动以在ScrollViewer UWP中水平滚动,c#,xaml,uwp,event-handling,scrollviewer,C#,Xaml,Uwp,Event Handling,Scrollviewer,我想启用在滚动时按住键盘上的SHIFT键以水平滚动ScrollViewer 我从中了解到,指针heelchanged事件就是我正在寻找的事件。但是,处理它不起作用,因为ScrollViewer在内部处理它,所以永远不会调用我的处理程序。为了解决这个问题,我使用了AddHandler方法,如本文所述 这很有效。。。但是在ScrollViewer运行其内部代码之后,似乎正在运行我的代码。其结果是ScrollViewer内容先垂直平移,然后水平平移。它们似乎是按这个顺序发生的,设置e.Handled=

我想启用在滚动时按住键盘上的SHIFT键以水平滚动
ScrollViewer

我从中了解到,
指针heelchanged
事件就是我正在寻找的事件。但是,处理它不起作用,因为
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>

您只需在
shift
keydown中禁用
VerticalScrollMode
,然后在keydup上启用它即可。无需更改
指针本身。它工作得非常好

Xaml


这似乎大部分是有效的。我在
ScrollViewer
中有内容,在X和Y方向上都要大得多。虽然按住SHIFT键允许水平滚动,但在水平滚动之前,
ScrollViewer
首先跳转到特定的垂直滚动值。。。无论我开始水平滚动时的垂直值是多少。想法?进一步检查表明,它的跳跃使得内容在
ScrollViewer
中垂直居中。设置MyScrollViewer.IsScrollInertiaEnabled=false;在键关闭和启用它。跳起来停下来。我已经编辑了我的答案
// 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;
    }
}
<ScrollViewer ZoomMode="Enabled" x:Name="MyScrollViewer"  HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible" >
   <Image Height="600" Width="500" Source="/Assets/1.jpg"></Image>
</ScrollViewer>
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;
        }
    }

}