Как сделать собственный обработчик событий? - PullRequest
1 голос
/ 15 ноября 2010

Я делаю проект Windows Form в C #, в котором я создал класс LabelX, который наследует System.Windows.Forms.Label, затем добавил свойство Mass типа float

Теперь мой вопрос: как мне справиться, когда значение Mass изменилось.

например:.
Когда пользователь вводит значение zero или less than zero
Я хочу отправить сообщение, что «Масса не может быть нулевой или отрицательной»

Ответы [ 5 ]

3 голосов
/ 15 ноября 2010

Если я правильно понимаю, есть две части. Во-первых, вам нужно обнаружить недопустимые значения и генерировать исключения. Во-вторых, вам нужно вызвать событие при изменении свойства. Это может быть достигнуто следующим образом.

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.

2 голосов
/ 15 ноября 2010

Попробуйте следующее:

// 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);
    }
}
1 голос
/ 15 ноября 2010

За пределами вашего класса 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 вашего базового объекта и выполнить любые необходимые действия.

0 голосов
/ 15 ноября 2010

Я совершенно уверен, что вы хотели бы «уволить» исключение в вашем случае.Это более логичная проблема, связанная с такой концепцией контрактов кода АОП.

Но если вы действительно хотите создать событие для него, вам нужно как минимум: 1) создать переменную хранения событий в классе меток

  public event EventHandler MassChanged;

2) в вашем свойстве (примечаниечто вы теряете возможность использовать функции кода поколения c # 3, для которых 'auto' реализует поле для хранения значения вашего свойства 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 для событий: текст ссылки

Опять же, я почти уверен, что вы не правильно обрабатываете исключения в приложении, если вам нужно событие для этого.Я имею в виду, что в этом нет ничего плохого, но события обычно не используются как средства проверки значений.

0 голосов
/ 15 ноября 2010

События - это общий шаблон, используемый в фреймворке.Процесс обычно включает в себя определение делегата, который будет использоваться в качестве обработчиков событий, объявление события с использованием обработчика, определение методов для вызова события, а затем подключение к свойствам логики для вызова события.

СообщениеВы описываете, лучше сделать как Исключение, но вот пример для определения события 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;
}

После этого, это просто вопрос регистрации обработчиков события и перехода оттуда.

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