Событие, запускающее событие - PullRequest
3 голосов
/ 22 июля 2010

У меня есть объект, который является частным в моем классе.Если этот объект запускает событие, я хочу передать событие тому, кто использует мой класс.В настоящее время я делаю это таким образом, я вставляю свой конструктор:

cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args));

Есть ли лучший способ сделать это, и есть ли какие-то ошибки, подобные классу, не будут утилизированы, потому что у него есть событие для себяМне нужно будет вручную отписаться в функции dispose?

Изменение отправителя с объекта обжига на this необязательно.

Полная версия тестового кода

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; }
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 22 июля 2010

event на самом деле похож на авто-свойство. Вы можете определить свои собственные методы add и remove, которые передают делегат непосредственно дочернему элементу управления, что устраняет дополнительный уровень косвенности:

public event EventHandler CheckChanged {
    add { cbName.CheckChanged += value; }
    remove { cbName.CheckChanged -= value; }
}

Это удалит лишние Delegate, хранящиеся в вашем классе (поскольку поле Delegate используется за кулисами стандартного события)

1 голос
/ 22 июля 2010

Что ж, это предотвратит сборку мусора для текущего объекта, пока cbName жив, но, похоже, это не проблема ... и это связано с тем, что у вас есть ссылка на this что бы вы ни делали (потому что вы хотите запустить обработчики этого объекта *).

Недостатком этого является то, что вы не можете отписаться (например, в методе 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 {};

В противном случае, если никто не подписался на событие, вы получите NullReferenceException при срабатывании cbName.CheckedChanged.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...