[UWP] ScrollViewer中的操作 [英] [UWP] Manipulations inside ScrollViewer

查看:90
本文介绍了[UWP] ScrollViewer中的操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


大家好,


我正在研究如何在ScrollViewer中使用直接操作。


我遇到了这样的问题,当我使用系统操作模式进行ScrollViewer滚动控制时效果很好,但操作根本不起作用。当我使用翻译模式操作时,但滚动 - 不是。



我在MainPage.xaml中有以下代码:

< Grid> 
< ScrollViewer Width =" 300"
Height =" 300"
VerticalAlignment =" Top"
Horizo​​ntalAlignment =" Center"
IsVerticalRailEnabled =" True"
VerticalScrollMode ="已启用"
VerticalScrollBarVisibility =" Auto">
<网格x:名称=" rootGrid">
< Grid.RowDefinitions>
< RowDefinition Height =" Auto" />
< RowDefinition Height =" Auto" />
< RowDefinition Height =" Auto" />
< RowDefinition Height =" Auto" />
< RowDefinition Height =" Auto" />
< /Grid.RowDefinitions>

< Grid Grid.Row =" 0"
高度="200"
Width =" 500"
背景="绿色" />

< Grid Grid.Row =" 1"
Margin =" 0,50,0,0"
高度="200"
Width =" 500"
背景="红色" />

< Grid Grid.Row =" 2"
高度="200"
Width =" 500"
背景="蓝色" />

< Grid Grid.Row =" 3"
高度="200"
Width =" 500"
背景="橙色"/>

< Grid Grid.Row =" 4"
高度="200"
Width =" 500"
Background =" DarkSlateGray" />
< / Grid>
< / ScrollViewer>

< Button x:Name =" systemButton"
Content =" System"
Width =" 150"
高度="48"
Horizo​​ntalAlignment =" Left"
VerticalAlignment =" Bottom" />

< Button x:Name =" translatesButton"
Content =" Translates"
Width =" 150"
高度="48"
Horizo​​ntalAlignment =" Right"
VerticalAlignment =" Bottom" />
< / Grid>

这在代码背后:

 public sealed partial class MainPage:Page 
{
public MainPage()
{
this.InitializeComponent();
this.Loaded + = OnLoaded;
}

private void OnLoaded(对象发送者,RoutedEventArgs routedEventArgs)
{
this.systemButton.Click + = this.OnSystemButtonClick;
this.translatesButton.Click + = this.OnTranslatesButtonClick;
this.rootGrid.ManipulationDelta + = this.OnRootGridManipulationDelta;
}

private void OnTranslatesButtonClick(对象发送者,RoutedEventArgs routedEventArgs)
{
this.rootGrid.ManipulationMode = ManipulationModes.TranslateX |
ManipulationModes.TranslateY |
ManipulationModes.TranslateInertia;
}

private void OnSystemButtonClick(object sender,RoutedEventArgs routedEventArgs)
{
this.rootGrid.ManipulationMode = ManipulationModes.System;
}

private void OnRootGridManipulationDelta(object sender,ManipulationDeltaRoutedEventArgs e)
{
Debug.WriteLine(" x:" + e.Delta.Translation.X +" | y:" + e.Delta.Translation.Y);
}
}

如何在ScrollViewer中正确使用直接操作?


来源:  https://1drv.ms/u/s!As4m3ySWSoqpwjpRAqboTxG210tE


感谢您的回复!


解决方案

Hello igor floru,


首先,对于ManipulationMode,我们必须根据

doc


你必须设置将
ManipulationMode 更改为系统或如果您想处理操作事件,例如

ManipulationStarted
。有关操作的更多信息,请参阅

快速入门:触摸输入


Rob在他的博客上澄清了我们无法接收操纵事件的原因:  我的所有手势都去了哪里? 我认为你可能已经知道了:b $ b已经知道:


"因为触摸操作需要非常敏感,所以Xaml应用程序可以使用称为
的Windows功能
直接操作
,用于处理渲染线程中的低级输入。直接操作检测触摸输入,例如滚动,平移和缩放。 ScrollViewer使用它快速,干净地滚动,应用程序可以通过Xaml Manipulation事件监听Direct Manipulation
,以响应地与渲染线程同步应用缩放,平移和旋转渲染变换。"


以下是您可以参考的一些评论:


1。 "最简单的方法是将所需的指针消息限制为阻止滚动的子项,并将其设置为处理自己的操作。"


2。 "不幸的是,如果应用程序需要滚动和手势(例如,检测CrossSlides对滚动),则没有好的解决方案。在这种情况下,在任何地方获取指针消息的唯一选择是在任何地方禁用直接操作
,但这也禁用滚动。要获得该功能,应用程序将需要检测滚动手势本身,然后使用ScrollToHorizo​​ntalOffset或ScrollToVerticalOffset或通过更新SelectedIndex将ScrollViewer导航到新位置。
这很棘手,比让ScrollViewer做它的事情要慢得多。如果可能的话应该避免。"


祝你好运,


Barry



Hi all,

I'm researching how to use direct manipulations inside ScrollViewer.

I ran into such a problem, when i using system manipulation mode for control inside ScrollViewer scroll works well, but manipulations doesn't work at all. And when i using translate modes manipulations works, but scroll - not.

I have the following code in MainPage.xaml:

<Grid>
        <ScrollViewer Width="300"
                      Height="300" 
                      VerticalAlignment="Top"
                      HorizontalAlignment="Center"
                      IsVerticalRailEnabled="True"
                      VerticalScrollMode="Enabled"
                      VerticalScrollBarVisibility="Auto">
            <Grid x:Name="rootGrid">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <Grid Grid.Row="0"
                      Height="200"
                      Width="500"
                      Background="Green"/>

                <Grid Grid.Row="1" 
                      Margin="0,50,0,0"
                      Height="200"
                      Width="500"
                      Background="Red"/>

                <Grid Grid.Row="2" 
                      Height="200"
                      Width="500"
                      Background="Blue"/>

                <Grid Grid.Row="3" 
                      Height="200"
                      Width="500"
                      Background="Orange"/>

                <Grid Grid.Row="4" 
                      Height="200"
                      Width="500"
                      Background="DarkSlateGray"/>
            </Grid>
        </ScrollViewer>
        
        <Button x:Name="systemButton" 
                Content="System"
                Width="150"
                Height="48"
                HorizontalAlignment="Left"
                VerticalAlignment="Bottom"/>

        <Button x:Name="translatesButton" 
                Content="Translates"
                Width="150"
                Height="48"
                HorizontalAlignment="Right"
                VerticalAlignment="Bottom"/>
    </Grid>

And this in code behind :

public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            this.systemButton.Click += this.OnSystemButtonClick;
            this.translatesButton.Click += this.OnTranslatesButtonClick;
            this.rootGrid.ManipulationDelta += this.OnRootGridManipulationDelta;
        }

        private void OnTranslatesButtonClick(object sender, RoutedEventArgs routedEventArgs)
        {
            this.rootGrid.ManipulationMode = ManipulationModes.TranslateX |
                                             ManipulationModes.TranslateY |
                                             ManipulationModes.TranslateInertia;
        }

        private void OnSystemButtonClick(object sender, RoutedEventArgs routedEventArgs)
        {
            this.rootGrid.ManipulationMode = ManipulationModes.System;
        }

        private void OnRootGridManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            Debug.WriteLine("x:" + e.Delta.Translation.X + " | y:" + e.Delta.Translation.Y);
        }
    }

How I can correctly use direct manipulations inside ScrollViewer ?

Source : https://1drv.ms/u/s!As4m3ySWSoqpwjpRAqboTxG210tE

Thanks for reply!

解决方案

Hello igor floru,

First of all, for the ManipulationMode we have to set it other than system or none based on the doc:

You must set the ManipulationMode to a value other than System or None if you want to handle manipulation events such as ManipulationStarted from UI elements in your app code. For more info on manipulations, see Quickstart: Touch input.

And the reason why we cannot receive Manipulation events have been clarified by Rob on his blog: Where did all my gestures go?. Which I think you may already know:

"Because touch manipulations need to be very responsive, Xaml apps tap into a Windows feature known as Direct Manipulation to handle input at a low level on the render thread. Direct Manipulation detects touch input such as scrolling, panning, and scaling. The ScrollViewer uses it to scroll swiftly and cleanly, and the app can listen to Direct Manipulation via the Xaml Manipulation events to apply scaling, translation, and rotation render transforms responsively in sync with the render thread."

And here are also some comments that you can reference:

1. "The easiest way is to restrict the needed pointer messages to a sub-item which blocks the scrolling and set it to handle its own manipulations."

2. "Unfortunately there is no good solution if the app needs both scrolling and gestures (for example, to detect CrossSlides against the scrolling). In this case the only option to get the Pointer messages everywhere is to disable Direct Manipulation everywhere, but that disables scrolling as well. To get that back the app will need to detect the scrolling gestures itself and then navigate the ScrollViewer to the new location with ScrollToHorizontalOffset or ScrollToVerticalOffset or by updating the SelectedIndex. This is tricky and will be noticeably slower than letting the ScrollViewer do its thing. It should be avoided if at all possible."

Best regards,

Barry


这篇关于[UWP] ScrollViewer中的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆