Как добавить событие в UserControl в C #? - PullRequest
25 голосов
/ 15 августа 2010

У меня есть UserControl, который содержит 3 метки. Я хочу добавить для него событие, которое происходит при изменении текста одной из меток.
Я использую Visual Studio 2010

Ответы [ 6 ]

52 голосов
/ 15 августа 2010

Сначала вам нужно объявить событие в вашем классе (вместе с вашими методами и конструкторами):

public event EventHandler LabelsTextChanged;

Затем вам нужно создать метод для обработки событий TextChanged отдельных меток.

private void HandleLabelTextChanged(object sender, EventArgs e)
{
    // we'll explain this in a minute
    this.OnLabelsTextChanged(EventArgs.Empty);
}

Где-то, вероятно, в конструкторе вашего элемента управления, вам необходимо подписаться на события TextChanged метки.

myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;

Теперь для метода HandleLabelsTextChanged.Мы могли бы поднять LabelsTextChanged напрямую;однако в рекомендациях по разработке .NET Framework говорится, что рекомендуется создать защищенный виртуальный метод OnEventName, чтобы поднять событие для нас.Таким образом, наследуемые классы могут «обрабатывать» событие, переопределяя метод OnEventName, который, как оказалось, имеет немного лучшую производительность, чем подписка на событие.Даже если вы думаете, что никогда не будете переопределять метод OnEventName, это хорошая идея, чтобы все равно привыкнуть делать это, поскольку это упрощает процесс создания событий.

Вот наш OnLabelsTextChanged:

protected virtual void OnLabelsTextChanged(EventArgs e)
{
    EventHandler handler = this.LabelsTextChanged;
    if (handler != null)
    {
        handler(this, e);
    }
}

Мы должны проверить на нулевое значение, поскольку событие без подписчиков является нулевым.Если бы мы попытались вызвать нулевое событие, мы бы получили NullReferenceException.Обратите внимание, что мы копируем событие EventHandler в локальную переменную, прежде чем проверять его на нулевое значение и вызывать событие.Если бы мы вместо этого сделали это так:

if (this.LabelsTextChanged != null)
{
    this.LabelsTextChanged(this, e);
}

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

Редактировать: Вот как должна быть расположена строка public event EventHandler LabelsTextChanged;:

namespace YourNamespace
{
    class MyUserControl : UserControl
    {
        // it needs to be here:
        public event EventHandler LabelsTextChanged;

        ...
    }
}

Здесь - руководящие принципы разработки структуры для разработки событий для дальнейшего чтения.

3 голосов
/ 15 августа 2010

Сначала вы должны объявить событие в вашем usercontrol, например:

public event EventHandler TextOfLabelChanged;

тогда вы должны вызывать функцию обратного вызова, которая связана с вашим событием (если оно есть) во время выполнения. Вы можете сделать это, обработав событие TextChanged метки следующим образом:

public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}

Вы можете иметь свой собственный объект EventArgs, если хотите.

где-то в вашем коде, вы должны привязать событие TextChanged метки к этому методу следующим образом:

_myLabel.TextChanged+=LabelTextChanged;
1 голос
/ 13 мая 2014

Существует очень простой способ сделать это!

В форме UserControl:

  1. изменить свойства на общедоступные для доступа везде

в главной форме, где вы используете UserControl:

.5: в области using добавить using userControl1=UserControl.userControl1

1.Добавить событие «Laod» в свой UserControl:

this.userControl1.Load += new System.EventHandler(this.userControl1_Load);

2. В userControl1_Load:

private void userControl1_Load(object sender, EventArgs e)
{
     (sender as UserControl1).label1.TextChanged += label1_TextChanged; 
     //add a 'TextChanged' event to the label1 of UserControl1 
     OR use direct cast:
     ((UserControl1) sender).label1.TextChanged += label1_TextChanged;

}

3. В метке 1_TextChanged:

 private void label1_TextChanged(object sender, EventArgs e)
 {
     //do whatever you want
 }
1 голос
/ 01 мая 2011

ошибка компиляции, которая говорит: «Ожидаемый класс, делегат, перечисление, интерфейс или структура» во второй строке, похоже, есть проблема с «event ...


Эти 2 строкидолжно быть ВНУТРИ объявления класса.

public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;
0 голосов
/ 16 ноября 2012

Вы должны объявлять event и delegate в пределах Namespace.Попробуйте ввести код в поле class.Он будет работать нормально.

0 голосов
/ 15 августа 2010
public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;

// ...

protected void MyTextBox_TextChanged(object sender, EventArgs e)
{
    if (LabelTextChanged != null) {
        LabelTextChanged(this, e);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...