WPF 禁用实时触摸

原文: WPF 禁用实时触摸

微软想把 WPF 作为 win7 的触摸好用的框架,所以微软做了很多特殊的兼容。为了获得真实的触摸消息,微软提供了 OnStylusDown, OnStylusUp, 和 OnStylusMove 事件。 本文告诉大家如何使用代码禁用 WPF 的触摸消息,解决一些问题。

在 win7 还提供了多点触摸 windows 消息 WM_TOUCH ,通过这两个 API 一个是 OnStylusDown 这些事件,另一个就是 WM_TOUCH ,用户可以拿到触摸消息。

这两个 API 是相互独立,依靠相同的 HWND 。

那么为什么需要禁用 WPF 的 RealTimeStylus ,因为在 WPF 触摸平台会禁用 WM_TOUCH 消息。如果想要使用 WM_TOUCH ,在 WPF 需要禁用 WPF 的触摸事件。

如果没有禁用,就无法拿到 WM_TOUCH 消息,这个方法可以让自己定义自己的触摸。

禁用的方法使用下面代码

	public static void DisableWPFTabletSupport()
{
    // Get a collection of the tablet devices for this window.  
    TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;

    if (devices.Count > 0)
    {   
        // Get the Type of InputManager.
        Type inputManagerType = typeof(System.Windows.Input.InputManager);
        
        // Call the StylusLogic method on the InputManager.Current instance.
        object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                    null, InputManager.Current, null);

        if (stylusLogic != null)
        {
            //  Get the type of the stylusLogic returned from the call to StylusLogic.
            Type stylusLogicType = stylusLogic.GetType();
            
            // Loop until there are no more devices to remove.
            while (devices.Count > 0)
            {
                // Remove the first tablet device in the devices collection.
                stylusLogicType.InvokeMember("OnTabletRemoved",
                        BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                        null, stylusLogic, new object[] { (uint)0 });
            }                
        }
               
    }
}

代码直接可以直接放在项目,代码是在微软文档复制。

虽然禁用微软提供的触摸事件,可以修复很多坑,但是禁用了也是有很多新的坑,不过我就不在这里告诉大家。自己尝试运行下面代码,然后试试程序。

为什么这样就可以禁用触摸,请看WPF 触摸到事件

Disable the RealTimeStylus for WPF Applications


本文会经常更新,请阅读原文: https://lindexi.gitee.io/lindexi/post/WPF-%E7%A6%81%E7%94%A8%E5%AE%9E%E6%97%B6%E8%A7%A6%E6%91%B8.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://lindexi.gitee.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

posted on 2019-01-04 10:31 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10218449.html

<think>好的,用户想在WPF中实现触摸屏的滚动操作,需要找方法或教程。首先,我需要回忆一下之前学过的WPF触摸处理相关知识,并结合提供的引用内容来组织答案。 用户提供的引用有三个,分别提到了不同的方法。引用[1]提到使用`local:TouchScrolling.IsEnabled="True"`来启用触摸滚动,看起来是自定义的附加属性。这可能是一个第三方库或者自定义实现的解决方案,需要进一步确认是否需要引入特定的命名空间或库。 引用[2]讨论了ScrollViewer无法触摸滚动的问题,解决方法是在Canvas控件的MouseEnter和MouseLeave事件中调整ScrollViewer的IsManipulationEnabled属性。这可能是因为某些子控件拦截了触摸事件,导致ScrollViewer无法正常响应,通过动态切换IsManipulationEnabled来解决问题。 引用[3]则是在ListView中通过处理ScrollChanged、PreviewMouseLeftButtonDown和MouseMove事件来实现触摸滚动,可能涉及到手动处理触摸事件或模拟滚动行为。 接下来,我需要将这些方法整理成步骤,并确保符合用户的问题。用户需要的是教程或实现方法,所以应该分步骤说明不同的解决方案,并指出各自的适用场景。 首先,使用ScrollViewer的内置属性可能最简单,比如设置PanningMode,这在WPF 4.0及以上支持触摸的设备上有效。然后,如果遇到子控件干扰的情况,引用[2]的方法可以解决问题,即在进入子控件时禁用ScrollViewer的操纵,离开时启用。另外,附加属性TouchScrolling.IsEnabled可能来自某个库,比如WPF Toolkit或第三方扩展,需要说明如何引用。 另外,可能需要处理手势或事件,如处理Manipulation事件来实现自定义滚动逻辑。对于更复杂的情况,比如自定义控件或需要精细控制触摸行为时,手动处理这些事件会更灵活。 需要注意的是,用户可能对WPF版本和使用的库不太清楚,所以应给出通用的方法,并提到可能的依赖库。同时,要确保示例代码正确,比如命名空间是否正确,事件处理是否匹配。 最后,生成相关问题时要围绕WPF触摸滚动的其他常见问题,比如性能优化、特定控件支持、与鼠标滚动的兼容性,以及第三方库推荐等。</think>在WPF中实现触摸屏滚动操作主要有以下几种方法,结合代码示例说明如下: ### 一、使用ScrollViewer内置触摸支持 1. **启用PanningMode属性** 在WPF 4.0及以上版本中,为`ScrollViewer`控件设置: ```xml <ScrollViewer PanningMode="Both" PanningDeceleration="0.01"> <!-- 内容 --> </ScrollViewer> ``` 该方式直接利用系统级触摸支持实现平滑滚动[^1]。 ### 二、处理子控件触摸冲突 2. **动态调整IsManipulationEnabled** 当子控件(如Canvas)与ScrollViewer存在事件冲突时,通过事件切换属性: ```xml <ScrollViewer x:Name="GridScrollViewer"> <Canvas MouseEnter="Canvas_OnMouseEnter" MouseLeave="Canvas_OnMouseLeave"/> </ScrollViewer> ``` ```csharp private void Canvas_OnMouseEnter(object sender, MouseEventArgs e) { GridScrollViewer.IsManipulationEnabled = false; // 禁用滚动器触摸 } private void Canvas_OnMouseLeave(object sender, MouseEventArgs e) { GridScrollViewer.IsManipulationEnabled = true; // 恢复滚动器触摸 } ``` 该方法可解决子控件拦截触摸事件的问题[^2]。 ### 三、使用附加属性增强支持 3. **引入TouchScrolling附加属性** 在XAML中添加命名空间引用后,为任意控件启用触摸滚动: ```xml xmlns:local="clr-namespace:YourNamespace.TouchExtensions" <ListView local:TouchScrolling.IsEnabled="True"/> ``` 该实现通常需要引用扩展库(如WPF Toolkit)。 ### 四、手动处理触摸事件 4. **通过Manipulation事件实现自定义滚动** ```csharp private void UIElement_OnManipulationDelta(object sender, ManipulationDeltaEventArgs e) { var transform = ((UIElement)sender).RenderTransform as TranslateTransform; if (transform == null) return; transform.Y += e.DeltaManipulation.Translation.Y; e.Handled = true; } ``` 此方案适用于需要完全自定义滚动逻辑的场景[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值