暂时停止表单事件的引发或处理?

2023-12-12

我的表单上有大量控件,并且在特定时间我想暂时停止处理所有事件。通常,如果我不想处理某些事件,我就会这样做:

private bool myOpRunning = false;

private void OpFunction()
{
    myOpRunning = true;
    // do stuff
    myOpRunning = false;
}

private void someHandler(object sender, EventArgs e)
{
    if (myOpRunning) return;
    // otherwise, do things
}

但我有很多处理程序需要更新。只是好奇 .NET 是否有比更新每个处理程序方法更快的方法。


您必须创建自己的机制来做到这一点。不过,这还不算太糟糕。考虑添加另一层抽象。例如,一个简单的类称为FilteredEventHandler检查 myOpRunning 的状态并调用真实的事件处理程序或抑制该事件。该类看起来像这样:

public sealed class FilteredEventHandler
{
    private readonly Func<bool> supressEvent;
    private readonly EventHandler realEvent;

    public FilteredEventHandler(Func<bool> supressEvent, EventHandler eventToRaise)
    {
        this.supressEvent = supressEvent;
        this.realEvent = eventToRaise;
    }

    //Checks the "supress" flag and either call the real event handler, or skip it
    public void FakeEventHandler(object sender, EventArgs e)
    {
        if (!this.supressEvent())
        {
            this.realEvent(sender, e);
        }
    }
}

然后,当您连接该事件时,请执行以下操作:

this.Control.WhateverEvent += new FilteredEventHandler(() => myOpRunning, RealEventHandler).FakeEventHandler;

When WhateverEvent被提出,它会调用FilteredEventHandler.FakeEventHandler method。该方法将检查标志并调用或不调用真正的事件处理程序。这在逻辑上与您已经在做的事情几乎相同,但是检查 myOpRunning 标志的代码仅位于一个位置,而不是散布在整个代码中。

编辑回答评论中的问题:

现在,这个例子有点不完整。完全取消订阅事件有点困难,因为您丢失了对已连接的 FilteredEventHandler 的引用。例如,你不能这样做:

this.Control.WhateverEvent += new FilteredEventHandler(() => myOpRunning, RealEventHandler).FakeEventHandler;
//Some other stuff. . .
this.Control.WhateverEvent -= new FilteredEventHandler(() => myOpRunning, RealEventHandler).FakeEventHandler; //Not gonna work!

因为您正在连接一名代表并取消另一名完全不同的代表!当然,两个委托都是 FakeEventHandler 方法,但那是一个实例方法,并且它们属于两个完全不同的 FilteredEventHandler 对象。

不知何故,您需要获取对您构造的第一个 FilteredEventHandler 的引用才能取消挂钩。像这样的东西是可行的,但它涉及跟踪一堆 FilteredEventHandler 对象,这可能并不比您试图解决的原始问题好:

FilteredEventHandler filter1 = new FilteredEventHandler(() => myOpRunning, RealEventHandler);
this.Control.WhateverEvent += filter1.FakeEventHandler;
//Code that does other stuff. . .
this.Control.WhateverEvent -= filter1.FakeEventHandler;

在这种情况下,我要做的就是让 FilteredEventHandler.FakeEventHandler 方法将其“this”引用传递给 RealEventHandler。这涉及更改 RealEventHandler 的签名以采用另一个参数:

public void RealEventHandler(object sender, EventArgs e, FilteredEventHandler filter);

或者将其更改为采用您创建的 EventArgs 子类,该子类保存对 FilteredEventHandler 的引用。这是更好的方法

public void RealEventHandler(object sender, FilteredEventArgs e);
//Also change the signature of the FilteredEventHandler constructor:
public FilteredEventHandler(Func<bool> supressEvent, EventHandler<FilteredEventArgs> eventToRaise)
{
  //. . .
}
//Finally, change the FakeEventHandler method to call the real event and pass a reference to itself
this.realEvent(sender, new FilteredEventArgs(e, this)); //Pass the original event args + a reference to this specific FilteredEventHandler

现在,被调用的 RealEventHandler 可以自行取消订阅,因为它具有对传递到其参数的正确 FilteredEventHandler 对象的引用。

不过,我最后的建议是不要做任何这样的事!Neolisk 在评论中指出了这一点。做这样复杂的事情就表明设计有问题。对于将来需要维护此代码的任何人(甚至是您,令人惊讶!)来说,都很难弄清楚所涉及的非标准管道。

通常,当您订阅事件时,您只执行一次,然后就忘记了 - 尤其是在 GUI 程序中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

暂时停止表单事件的引发或处理? 的相关文章

  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz

随机推荐

  • Mysql 表分区基于列/id 的最后一位数字

    我想根据员工 ID 的最后一位创建分区 IE all ids ending with 0 go to first partition ending with 1 go to second partition and so on 这样我想创建
  • 使用多行字符串的正则表达式修剪行并缩小空格

    I m using a php function want to create a function to trim all unnecessary white spaces from a multi line string 它不起作用的正
  • 如何在静态方法中访问下拉列表

    我有以下静态方法 public static List
  • 如何为节点设置预加载文件?

    有没有办法在每次运行之前预加载一些文件node 交互式 就像 vimrc bash profile etc I use node主要是交互方式 我使用该模块CSV很多 有没有办法避免打字require csv 每次我开始node 创建初始化
  • JBoss/Wildfly AS 内重复格式化的记录器输出

    看来 我不能排除 JBoss Wildfly 日志子系统 我有一个 Java EE 耳朵 希望将 slf4j API 与 log4J2 实现一起使用 我的目的是禁用 JBoss 日志记录子系统 让我的 slf4j log4j2 实现处理日志
  • 如何在 Blackberry AutoCompleteField 中以字符串形式获取所选项目?

    使用 Blackberry 自动完成字段时如何以字符串形式获取所选项目 我目前能够获取选定的索引 我正在重写 AutoCompleteField 类中的 onSelect 方法 如下所述 自动完成类参考 API JDE 5 0 下面的代码片
  • Kotlin 惰性属性依赖于 init 中初始化的另一个属性

    我在 Kotlin 有以下课程 class Example val name String val lazyVar String by lazy name something else init name StackOverflow 当我使
  • 如何获取文档的数量并以有效的方式过滤它们? (猫鼬)

    我正在实现搜索功能 即在 mongoDB 中查找文档 我想要 skip x and limit x on result 来模拟分页结果 但是我可以获取文档总数 在跳过和限制之前 并立即获取过滤结果吗 产生预期输出的代码 db Datas f
  • 我无法在 R 3.2.0 中加载开发工具

    我正在使用 Rstudio 开发 R 包 到目前为止 我使用 R 3 1 2 并且一切正常 最近我将 R 更新到了 3 2 0 版本 并且我也更新了软件包 现在 加载开发工具时 gt library devtools Error in in
  • 创建控件的透明部分以查看其下方的控件

    我已经修改了超级上下文菜单条在 CodeProject 找到的 可以满足我的一些项目需求 我将其用作地图标记的工具提示GMap NET 地图控件 下面是它的示例 我想做的就是通过让它看起来更像一个泡沫来稍微美化一下 类似于旧的 Google
  • 将秒转换为天、小时、分钟和秒

    我有一个 Javascript 计时事件 带有一个带有停止按钮的无限循环 单击开始按钮时它将显示数字 现在我希望将这些数字转换为 4 小时 3 分钟 50 秒之类的内容 var c 0 var t var timer is on 0 fun
  • 如何迭代求BST的高度?

    public void HeightIterative int counter 0 int counter2 0 TreeNode current root if current null while current LeftNode nu
  • 将 PHP 页面的 html 响应返回到变量

    我正在尝试生成一封电子邮件 其中包含一些通过另一个 PHP 文件创建的 HTML 电子邮件生成文件由每小时运行的 cron 运行 存在另一个文件 可生成电子邮件所需的 HTML HTML 生成文件没有我可以调用的函数 例如 emailBod
  • Pandas groupby max - 多列

    在 pandas 中分组到最大值后 如何完全沿着 max 值显示匹配的行结果 df data loc no std date result date result result df groupby no std date result d
  • 如何滚动警报控制器中的操作? Xcode 8、Swift 3、IOS

    请帮忙 我是个大菜鸟 我从各种来源收集了这段代码 所以我真的不知道我在做什么 我的警报控制器显示我可以写入的文本字段 取消 操作 确定 操作 它还显示多个 输入要标记的关键字 操作 它有太多的操作 我需要的大约 20 个关键字操作 以至于它
  • 了解 VBScript 中的 ON ERROR

    我正在尝试修改 vbscript 并将其按照指示转换为 Powershell 我的函数 SearchAD 有一段出现错误的代码 on error resume next Set objRS command execute SearchAD
  • 无法生成 DialogFlow v2 访问令牌

    在版本 1 中 这就是我与 DialogFlow Api 通信的方式 fetch configs baseUrl query v 20150910 body JSON stringify query text lang en session
  • 请解释一下这个 requestAnimationFrame 习语

    有很多地方 例如如何使用requestAnimationFrame 修复window requestAnimationFrame如下 我不明白为什么赋值的右侧被包装到函数调用中 window requestAnimFrame functio
  • 查找 Git 分支创建者

    我想知道是谁创建了一个分支 我可以通过以下方式做到这一点 git branch a xargs L 1 bash c echo 1 git log pretty format H an 1 1 但是 这会返回每个分支的最后一个提交者 而不一
  • 暂时停止表单事件的引发或处理?

    我的表单上有大量控件 并且在特定时间我想暂时停止处理所有事件 通常 如果我不想处理某些事件 我就会这样做 private bool myOpRunning false private void OpFunction myOpRunning