在 WPF 中,如果我们要做拖动效果,通常会调用一下 CaptureMouse/CaptureStylus 以便当鼠标或手指离开控件的时候依然能够响应 MoveUp 事件。不知有没有注意到这两个函数其实是有 bool 返回值的?——是的,它们可能会失败。


在调试一个项目代码的时候,我就发现了这种失败,观察返回值确实是 false,然而为什么呢?

查看 .Net Framework 的源码 我们发现,CaptureMouse 最终调到了 Mouse.Capture 方法:

public static bool Capture(IInputElement element)
{
return Mouse.PrimaryDevice.Capture(element);
}

然后一步步调到了 bool Capture(IInputElement element, CaptureMode captureMode),而其中对是否可 Capture 的关键性影响代码就在这个方法内部。为了便于理解,我把他改成了下面这样,是等价的:

[Pure]
private static bool CanCapture(IInputElement element)
{
if (element is UIElement e)
{
return e.IsVisible && e.IsEnabled;
}
if (element is ContentElement ce)
{
return ce.IsEnabled;
}
if (element is UIElement3D e3D)
{
return e3D.IsVisible && e3D.IsEnabled;
}
return true;
}

这段代码感兴趣可以拿走,以便在 Capture 之前可以进行预判。

从这段代码可以很清楚地知道,如果元素已不可见 (IsVisiblefalse) 或者不可用(IsEnabledfalse),则不可 Capture

以此为线索,果然发现调试的项目中在 MouseDown 事件里把元素隐藏了。

总结:

  • 如果元素不可见或不可用,则 Mouse.Capture 会失败。

顺便还发现一个问题,Stylus.Capture(IInputElement) 中居然直接调用的是 Mouse.Capture(IInputElement)

CaptureMouse/CaptureStylus 可能会失败的更多相关文章

  1. Dll中的方法向外返回dynamic类型可能会失败

    如果Dll中有某个类的方法返回dynamic实例,并且dynamic对象实际实例为匿名类类型,则Dll的外部使用者可能最终无法正常使用此dynamic对象.当使用此dynamic对象时,可能会遇到x属 ...

  2. 我遇到的WPF的坑

    转自 林德熙Blog 本文:我遇到的WPF的坑 目录 单例应用在多实例用户无法使用 标记方法被使用 当鼠标滑过一个被禁用的元素时,让ToolTip 显示 获取设备屏幕数量 获取当前域用户 绑定资源文件 ...

  3. 2019-8-28-WPF-开发

    title author date CreateTime categories WPF 开发 lindexi 2019-8-28 11:3:39 +0800 2018-2-13 17:23:3 +08 ...

  4. REDIS持久化报错失败

    redis log报错: [7666] 15 Jan 00:22:36.028 # Error moving temp DB file on the final destination: Invali ...

  5. 在Xcode 6 beta里编译Cocos2d-x iOS项目时失败

    转载 在Xcode 6 beta里编译Cocos2d-x iOS项目时可能会失败,提示如下错误: Undefined symbols for architecture i386: "_fwr ...

  6. C++ new失败的处理

    我们都知道,使用 malloc/calloc 等分配内存的函数时,一定要检查其返回值是否为“空指针”(亦即检查分配内存的操作是否成功),这是良好的编程习惯,也是编写可靠程序所必需的.但是,如果你简单地 ...

  7. 解决安装失败的 Internet Explorer 11

    注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成.微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章.然而由机器翻译的文章并不总是完美的.它 ...

  8. Ubuntu-linux云服务器下安装开启虚拟环境失败解决办法

    为什么要安装虚拟环境? 1.某些项目需要安装旧的包,开发相应功能 2.项目开发时,安装部分环境不希望影响整机环境 如何安装? 首先安装python 安装pip工具 sudo apt-get insta ...

  9. LoadLibrary 失败的解决

    工作中遇到调用Loadlibrary 偶发失败的问题,不是必现,而且这种错误只是在程序初始化的时候出现,初始化成功后当然不会调用,而初始化也不是经常做的动作,所以查找原因起来比较麻烦,调试过程中发现有 ...

随机推荐

  1. Enter键禁止表单提交

    Enter键禁止表单提交js代码: //禁用Enter键表单自动提交 document.onkeydown = function (event) { var target, code, tag; if ...

  2. php调用mysql存储过程

    MYSQL存储过程 原文链接:http://blog.sina.com.cn/s/blog_52d20fbf0100ofd5.html 一.存储过程简介(mysql5.0以上支持) 我们常用的操作数据 ...

  3. url 、src 、href 的区别

    url.href.src 详解 现自己居然没把url.href.src关系及使用搞清楚,今天就理一下.主要包括:url.src.href定义以及使用区别. URL(Uniform Resource L ...

  4. form表单提交数据的数据格式

    form表单提交的数据格式默认是 enctype="application/x-www-form-urlencoded"这样将input框的数据与input框的name属性以键值对 ...

  5. poj2187凸包最远点对

    暴力过了 #include<map> #include<set> #include<cmath> #include<queue> #include< ...

  6. Hibernate中"二级缓存"配置

    实体类 : package cn.happy.entity; public class Emp { private Integer empNo; private String empName; pub ...

  7. python类常用装饰器

    class Myclass(object): def __init__(self): pass #必须实例化才能调用 def sayhi(self): print 'hello' #静态方法,跟类没什 ...

  8. H3C Huawei 交换机 IPv6环境配置

    # 使能IPv6报文转发功能. <Sysname> system-view [Sysname] ipv6 # 使能DHCPv6服务器功能. <Sysname> system-v ...

  9. RabbitMQ(6) 集群部署

    单节点部署 rabbitmq单节点部署比较简单,可以使用apt-get等工具快速安装部署. wget -O- https://www.rabbitmq.com/rabbitmq-release-sig ...

  10. weblogic、hibernate 包冲突

    解决办法: 在weblogic 配置  [paths]项中 添加antlr-2.7.7.jar,该jar包应该位于引用weblogic.jar之前,使启动时不再加载weblogic中的低版本的antl ...