C++/CLI 事件有监听器吗?

2024-03-25

在 C# 中,我可以检查事件是否有任何侦听器:

C# 示例:

public static event EventHandler OnClick;

if (OnClick != null)
    OnClick(null, new EventArgs() );

在 C++/CLI 中,不需要检查事件是否为 null。

C++/CLI 示例:

delegate void ClickDelegate( Object^ sender, MyEventArgs^ e );
event ClickDelegate^ OnClick;

OnClick (sender, args);

但是,在我正在处理的项目中,如果没有侦听器,我不想构造 MyEventArgs 对象。

如何查明 OnClick 是否有 C++ 侦听器?


基于与 @BenVoigt 对 @svick 的原始答案和新答案的评论讨论有关 C++/CLI 事件的 MSDN 文章 http://msdn.microsoft.com/en-us/library/58cwt3zh.aspx#code-snippet-2,我创建了一个最小的示例来说明如何正确执行此操作。此代码在面向 .NET 4.5 的 Visual Studio 2013 CLR 项目模板中编译和运行。我尚未在其他运行时和目标上进行测试,但它仅使用基本的 .NET 组件。

TL;DR:

  • 将支持字段设置为私有

  • 锁定每个添加、删除和发起呼叫System::Threading::Monitor

  • 使用标准事件处理程序约定:

      void MyEventHandler(Object ^sender, MyEventArgs ^e);
    
  • Use += and -=除非支持字段是nullptr

我的解决方案:

// compile with: /clr
#include "stdafx.h"

using namespace System;
using System::Threading::Monitor;

public delegate void MyDelegate(Object ^sender, EventArgs ^e);

ref class EventSource {
private:
    MyDelegate ^myEvent;
    Object ^eventLock;

public:
    EventSource()
    {
        eventLock = gcnew Object();
    }

    event MyDelegate^ Event {
        void add(MyDelegate^ handler) {
            Monitor::Enter(eventLock);
            if (myEvent == nullptr)
            {
                myEvent = static_cast<MyDelegate^> (
                            Delegate::Combine(myEvent, handler));
            }
            else
            {
                myEvent += handler;
            }
            Monitor::Exit(eventLock);
        }

        void remove(MyDelegate^ handler) {
            Monitor::Enter(eventLock);
            if (myEvent != nullptr)
            {
                myEvent -= handler;
            }
            Monitor::Exit(eventLock);
        }

        void raise(Object ^sender, EventArgs ^e) {
            Monitor::Enter(eventLock);
            if (myEvent != nullptr)
                myEvent->Invoke(sender, e);
            Monitor::Exit(eventLock);
        }
    }

    void Raise()
    {
        Event(this, EventArgs::Empty);
    }
};

public ref struct EventReceiver {
    void Handler(Object ^sender, EventArgs ^e) {
        Console::WriteLine("In event handler");
    }
};

int main() {
    EventSource ^source = gcnew EventSource;
    EventReceiver ^receiver = gcnew EventReceiver;

    // hook event handler
    source->Event += gcnew MyDelegate(receiver, &EventReceiver::Handler);

    // raise event
    source->Raise();

    // unhook event handler
    source->Event -= gcnew MyDelegate(receiver, &EventReceiver::Handler);

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

C++/CLI 事件有监听器吗? 的相关文章

  • 当文本框为空时,C++ Windows 窗体应用程序出现未处理的异常错误

    我正在 Visual Studio 中为 C 课程构建温度转换应用程序 它是一个 Windows 窗体应用程序 我的问题是 当我运行应用程序时 如果我没有在 txtFahrenheit 或 txtCelsius2 文本框中输入任何内容 我会
  • onKeyDown 事件不适用于 React 中的 div

    我想在 React 中的 div 上使用 keyDown 事件 我愿意 componentWillMount document addEventListener keydown this onKeyPressed bind this com
  • 使用 SWING 编写触摸屏应用程序

    我想知道应用程序 UI 中的按钮应该监听哪些事件 鼠标点击 那么按下和释放事件又如何呢 通过触摸屏点击时它们是否相同 谢谢 托梅尔 大多数触摸屏只是模拟鼠标 所以如果您的需求很简单 您不需要做任何特殊的事情 JButtons 仍然触发 Ac
  • 使用 jQuery 在 AngularJS 元素指令上绑定事件

    我在 AngularJS 中有一个指令 module angular module demoApp null module directive sample function return restrict E transclude tru
  • jQuery鼠标的.click()是通过键盘导航启动的

    我发现 jQuery 的奇怪行为click事件 如果我们使用键盘导航 辅助功能情况 则通过 Enter 或 Space 启动单击 这取决于我们使用的是哪个 HTML 元素 jsfiddle 上有一个测试页面 您可以尝试在结果框架中使用键盘导
  • (python) matplotlib pyplot show() .. 是否阻塞?

    我遇到了这个麻烦show 一遍又一遍 我确信我做错了什么 但不确定做我想做的事情的 正确 方法 我认为 我想要的是某种方法来阻塞主线程 直到 GUI 线程中发生事件 这样的事情第一次起作用 from matplotlib import py
  • 使用 jQuery 将播放/暂停/结束功能绑定到 HTML5 视频

    我正在尝试绑定play pause and ended使用 jQuery 的事件但有一个问题 当我右键单击视频并选择播放或暂停时 图标会正确更改 当我单击播放按钮时 它会更改为暂停 但如果我单击暂停按钮继续播放视频 它不会更改为再次播放 谁
  • 当元素被覆盖时取消 mouseout 事件

    希望这个 JSFiddle 能比我的话更好地说明这个问题 http jsfiddle net pmwRc 6 http jsfiddle net pmwRc 6 当地图悬停时 我在图像地图上显示绝对定位的 H4 作为标签 但是 当鼠标指针移
  • MySQL 监听通知等效项

    是否有相当于 PostgresQL 的notify http www postgresql org docs 9 1 static sql notify html and listen http www postgresql org doc
  • Google Closure 事件委托 a'la jQuery live/on

    我需要将事件委托给新创建的元素 我需要将处理程序附加到它们的创建事件 类似于 onCreate 我不想在创建后通过寻址将事件绑定到元素 jQuery element click function 我更喜欢类似的东西 on document
  • Python ctypes:SetWindowsHookEx 回调函数从未被调用

    我正在尝试用 Python 编写一个程序 该程序可以识别何时显示警报框 对话框 它正在处理多个监视器 我希望它在任务栏图标闪烁 弹出错误 通知等时在辅助监视器上显示可视化效果 据我所知 检测这些事件的方法是使用消息挂钩 如下所述 http
  • 如何使用 JavaScript 阻止浏览器默认的退格按钮历史记录操作?

    有没有办法防止用户在浏览器中按退格键时发生默认操作 我不需要阻止用户离开 只需阻止用户执行默认的退格操作即可 我需要退格键来做一些不同的事情 这是一个游戏 我尝试过但没有成功 window addEventListener keydown
  • onChange 事件在哪个权威规范中进行了详尽的定义?

    我有点惊讶地发现 html 文档中的 onChange 事件在文本输入或文本区域上触发 而不是在其值实际更改时触发 而是仅在焦点离开元素时触发 当然 如果其值已更改 所以我一直在寻找说明这一点的规范 但找不到 我可以找到数以百万计的教程来解
  • Android:如何创建MotionEvent?

    MotionEvent没有获取构造函数 我想在单元测试中手动创建MotionEvent 那么如何获取它 谢谢 您应该使用静态之一obtain的方法MotionEvent类来创建一个新事件 最简单的方法 除了从现有事件包装新事件之外 是 st
  • 代表和活动之间有什么区别?

    代表和活动之间有什么区别 两者不都包含对可以执行的函数的引用吗 An Event声明增加了一层抽象和保护delegate实例 此保护可防止委托的客户端重置委托及其调用列表 并且仅允许在调用列表中添加或删除目标
  • 当用户关闭 IE 时显示消息框

    当用户关闭 IE 时 是否有 JavaScript 提示消息框 我尝试寻找代码示例很长一段时间但失败了 提前致谢 乔治 这是我的 html 代码 但有以下错误 有任何想法吗 为了帮助保护您的安全 Internet Explorer 已限制此
  • 自定义 Javascript EventManager - 请帮我完成

    我正在尝试创建一个自定义 javascript EventManager 类 我采用了 Grant Skinner 在他的 essel js 框架中使用的格式来创建类 并且需要坚持使用它 在这一点上我真的迷失了 我认为 至少在概念意义上 我
  • 如何在alert()之后给予focus()?

    我有类似的东西
  • as3 事件 - 类型强制失败?

    我正在将事件从孩子发送到父母 swf 它工作正常 直到我使用预加载器 swf 加载父级 然后父级停止从子级获取事件 我现在收到此错误 TypeError Error 1034 Type Coercion failed cannot conv
  • 如何在 C++/CLI 中显式/隐式实现接口成员?

    在 C CLI 中与此等效的内容是什么 class Explicit IClonable void IClonable Clone class Implicit IClonable public void Clone 正如 nobugz 所

随机推荐