C# 事件触发事件
我有一个对象在我的类中是私有的。如果该对象触发一个事件,我希望将该事件传递给使用我的类的任何对象。目前我是这样做的,我在构造函数中加入了:C# 事件触发事件,c#,events,.net-4.0,C#,Events,.net 4.0,我有一个对象在我的类中是私有的。如果该对象触发一个事件,我希望将该事件传递给使用我的类的任何对象。目前我是这样做的,我在构造函数中加入了: cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args)); 有没有更好的方法来做到这一点,是否有任何类似于类不会被释放的问题,因为它本身有一个事件,我需要在dispose函数中手动取消订阅 将发送器从激发对象更改为此是可选的 测试代码的完整版本 using Sy
cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args));
有没有更好的方法来做到这一点,是否有任何类似于类不会被释放的问题,因为它本身有一个事件,我需要在dispose函数中手动取消订阅
将发送器从激发对象更改为此
是可选的
测试代码的完整版本
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace placeholder
{
internal class FilterBase : UserControl, IFilterObject
{
public FilterBase(string name)
{
InitializeComponent();
cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args));
cbName.Name = name;
this.Name = name;
}
private CheckBox cbName;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cbName = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// cbName
//
this.cbName.AutoSize = true;
this.cbName.Location = new System.Drawing.Point(4, 4);
this.cbName.Name = "cbName";
this.cbName.Size = new System.Drawing.Size(79, 17);
this.cbName.TabIndex = 0;
this.cbName.Text = "Filter Name";
this.cbName.UseVisualStyleBackColor = true;
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.Controls.Add(this.cbName);
this.Name = "Filter Name";
this.Size = new System.Drawing.Size(86, 24);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
public event EventHandler CheckChanged;
public bool Checked
{
get { return cbName.Checked; }
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统图;
使用系统数据;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间占位符
{
内部类FilterBase:UserControl、IFilterObject
{
公共过滤器数据库(字符串名称)
{
初始化组件();
cbName.CheckedChanged+=((发送方,参数)=>this.CheckedChanged(this,参数));
cbName.Name=Name;
this.Name=Name;
}
私人姓名;
///
///必需的设计器变量。
///
private System.ComponentModel.IContainer components=null;
///
///清理所有正在使用的资源。
///
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域组件设计器生成的代码
///
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
///
私有void InitializeComponent()
{
this.cbName=new System.Windows.Forms.CheckBox();
这个.SuspendLayout();
//
//cbName
//
this.cbName.AutoSize=true;
this.cbName.Location=新系统.图纸.点(4,4);
this.cbName.Name=“cbName”;
this.cbName.Size=新系统.Drawing.Size(79,17);
this.cbName.TabIndex=0;
this.cbName.Text=“过滤器名称”;
this.cbName.UseVisualStyleBackColor=true;
//
//用户控制1
//
此.AutoScaleDimensions=新系统.Drawing.SizeF(6F,13F);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize=true;
this.AutoSizeMode=System.Windows.Forms.AutoSizeMode.growtandshrink;
this.Controls.Add(this.cbName);
this.Name=“过滤器名称”;
该尺寸=新系统图纸尺寸(86,24);
此选项为.resume布局(false);
这个。执行布局();
}
#端区
公共事件事件处理程序已更改;
公共图书馆检查
{
获取{return cbName.Checked;}
}
}
}
好吧,这将防止当前对象在cbName
处于活动状态时被垃圾收集,但听起来这不太可能是个问题。。。这是一个固有的事实,即无论您做什么,您都有一个对this
的引用(因为您想要启动这个对象的CheckChanged处理程序)
这样做的一个缺点是,即使您想取消订阅,也无法取消订阅(例如,在Dispose方法中)。另一种方法是使用实际方法:
private void CbNameCheckedChangedHandler(object sender, EventArgs e)
{
CheckedChanged(this, args);
}
...
cbName.CheckedChanged += CbNameCheckedChangedHandler;
// If you ever want to remove the handler
cbName.CheckedChanged -= CbNameCheckedChangedHandler;
请注意,这都是假设您的CheckedChanged
事件是空安全的,例如,它声明为:
public event EventHandler CheckedChanged = delegate {};
否则,如果没有人订阅该事件,则当触发
cbName.CheckedChanged
时,您将得到一个NullReferenceException
。事件实际上类似于自动属性。您可以定义自己的add
和remove
方法,将委托直接传递给子控件,从而删除额外的间接级别:
public event EventHandler CheckChanged {
add { cbName.CheckChanged += value; }
remove { cbName.CheckChanged -= value; }
}
这将删除存储在类中的额外
委托
(因为在标准事件的后台使用了委托
字段)感谢空引用警告!很酷,我不知道。有没有什么方法可以让我的蛋糕和吃它也改变发件人从cbName到FilterBase使用类似的东西?像往常一样,Jon Skeet在这里有一篇关于事件工作原理的伟大文章:。如果线程安全适用于您的情况,请务必了解线程安全。