如何制作自己的事件处理程序?

时间:2010-11-15 17:41:45

标签: c# .net event-handling

我正在用C#创建一个Windows窗体项目,我在其中创建了一个继承LabelX的类System.Windows.Forms.Label,然后添加了一个浮点类型的属性Mass

现在,我的问题是,当Mass的值发生变化时,我该如何处理。

e.g:
 当用户输入值zeroless than zero时  我想发消息“质量不能为零或负面”

5 个答案:

答案 0 :(得分:3)

如果我正确地解释了这一点,那么这有两个部分。首先,您需要检测无效值并抛出异常。其次,您需要在属性更改时引发事件。这可以通过以下方式实现。

private float mass;
public float Mass
{
    get
    {
        return this.mass;
    }

    set
    {
        if (value <= 0.0F)
        {
            throw new ArgumentOutOfRangeException("Mass cannot be zero or negative.");
        }

        if (this.mass != value)
        {
            this.mass = value;
            OnMassChanged(EventArgs.Empty);
        }
    }
}

public event EventHandler MassChanged;

protected virtual void OnMassChanged(EventArgs args)
{
    var handler = this.MassChanged;
    if (handler != null)
    {
        handler(this, args);
    }
}

要显示无效条目的消息,您应该在调用周围设置try \ catch块以设置Mass并抓住ArgumentOutOfRangeException。< / p>

答案 1 :(得分:2)

尝试以下方法:

// Created an empty form with a LabelX control on it.
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    // Added this event from the property manager.
    private void labelX1_MassChanged(object sender, EventArgs e)
    {
        var label = (LabelX)sender;

        if (label.Mass <= 0.0)
            MessageBox.Show("Mass is less than or equal to 0");
    }
}

public class LabelX : Label
{
    private float _mass;

    public float Mass
    {
        get { return _mass; }
        set
        {
            if (!value.Equals(_mass))
            {
                _mass = value;
                OnMassChanged(EventArgs.Empty);
            }
        }
    }

    public event EventHandler MassChanged;

    protected virtual void OnMassChanged(EventArgs e)
    {
        if (MassChanged != null)
            MassChanged(this, e);
    }
}

答案 2 :(得分:1)

在LabelX类之外,创建以下类:

public class MassChangedEventArgs : EventArgs
{
   public float Mass { get; private set; }

   public MassChangedEventArgs(float mass)
   {
     this.Mass = mass;
   }
}

同样在LabelX类之外,创建以下委托。这将是你的事件处理程序。

public delegate void MassChangedEventHandler(object sender, MassChangedEventArgs e);

在LabelX类中,创建要广播的事件:

public class LabelX
{
   public event MassChangedEventHandler MassChanged;
   //the rest of your code here...
}

您还需要创建一个用于触发事件的私有实例方法。

public class LabelX
{
   public event MassChangedEventHandler MassChanged;

   private void OnMassChanged()
   {
       if(MassChanged!=null)
          this.MassChanged(this, new MassChangedEventArgs(this.Mass));
   }
   //the rest of your code here...
}

最后,每当您的Mass属性发生变化时,请调用OnMassChanged。例如:

public class LabelX
{
   private float mass;
   public float Mass
   {
       get
       {
         return mass;
       }
       set
       {
         mass = value;
         OnMassChanged();
       }
   }

   public event MassChangedEventHandler MassChanged;

   private void OnMassChanged()
   {
       if(MassChanged!=null)
          this.MassChanged(this, new MassChangedEventArgs(this.Mass));
   }

   //the rest of your code here...
}

如果要基于每个实例处理该事件,您只需要使用基础对象的MassChanged事件注册一个侦听器,并执行所需的任何操作。

答案 3 :(得分:0)

事件是框架中使用的常见模式。该过程通常涉及定义要用作事件处理程序的委托,使用处理程序声明事件,定义引发事件的方法,然后连接到提升事件的逻辑属性。

您描述的消息最好以异常方式完成,但这是定义MassChanged事件的示例。

// Define event args if you have additional
// information to pass to your event handlers
public class MassChangedEventArgs : EventArgs
{
    public MassChangedEventArgs(int oldMass)
    {
        OldMass = oldMass;
    }
    public int OldMass { get; private set; }
}

public class SomeObject
{
    // There's a generic event handler delegate that can be
    // used so you only need to define the event arguments.
    public event EventHandler<MassChangedEventArgs> MassChanged;

    // Convenience method to raise the event
    protected virtual void OnMassChanged(MassChangedEventArgs e)
    {
        if (MassChanged != null)
            MassChanged(this, e);
    }

    public int Mass
    {
        get
        {
            return mass;
        }
        set
        {
            // Your checks here
            if (value <= 0)
                throw new ArgumentOutOfRangeException("Mass", "Mass can't be zero or negative");
            // Should only raise the event if the new value is different
            if (value != mass)
            {
                // Change the mass
                MassChangedEventArgs e = new MassChangedEventArgs(mass);
                mass = value;
                // Raise the event
                OnMassChanged(e);
            }
        }
    }

    private int mass;
}

在那之后,只需要在事件中注册处理程序并从那里开始。

答案 4 :(得分:0)

我很确定你想在你的情况下“解雇”一个例外。 这更像是一个验证逻辑问题,这样的AOP代码契约概念。

但是如果你真的想为它创​​建一个事件,你必须至少: 1)在标签类

中创建一个事件存储变量
  public event EventHandler MassChanged;

2)在你的财产中(注意你没有能力使用c#3的代码生成功能)                      “自动”实现该字段以存储您的Mass属性值

 public bool Mass
        {
            get { return _mass; }
            set { 
                  // check if value is invalid (0 or less) && that event subscribers exist
                  if(value<=0 && MassChanged != null) { MassChanged(this, null); }
                  else // otherwise assign ...
                  {  
                  _mass = value; 
                  }                

                }
        }

3)创建类型为EventHandler

的事件处理程序

最好阅读有关事件的msdn文章:link text

我再次确信您没有在应用中正确处理异常 如果你需要一个事件。我的意思是没有错,但事件是 通常不用作价值验证的手段。