Настраиваемые пользовательские элементы управления и события c #

Я создаю приложение Windows Forms с использованием C #, я создаю множество настраиваемых пользовательских элементов управления, и мой графический интерфейс представляет собой комбинацию этих пользовательских элементов управления, проблема в том, что когда я устанавливаю событие для этих пользовательских элементов управления из основной формы, событие не срабатывает, но если я установил это событие из элементов управления сам и установил обработчик событий для всех элементов внутри этого элемента управления на этот обработчик событий, он работает нормально, и, насколько я обернул элементы управления, я должен углубиться, чтобы установить события и обработчики событий, на самом деле это будет стоить больше накладных расходов "Что я не хочу". бывший:

В основной форме у меня есть элемент управления с именем «Пациент», который является элементом управления пользователя. Если я установлю событие щелчка для этого элемента управления из основной формы, он не сработает.

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

public event EventHandler PatientCliecked;

private void PatientClicked()
{
    if (this.PatientCliecked != null)
    this.PatientCliecked(new object(), new EventArgs());
}

private void ProcessPatientClickedEvent(object sender, EventArgs e)
{
    PatientClicked();
}

Мой вопрос: есть ли другой способ сделать это или это логика .NET?


person user2151551    schedule 17.09.2013    source источник
comment
if I set the click event for this control from the main form it will not fire --- ›Не могли бы вы пояснить? Как это сделать, любой код?   -  person King King    schedule 17.09.2013
comment
Итак, чтобы избежать нарушения уникальности имени в классе, вы на самом деле назвали событие PatientCli**e**cked? Это нельзя, потому что люди станут морщинистыми и заболеют морской болезнью. Вы должны использовать суффиксы или префиксы английского языка, например: event EventHandler PatientClicked вместо private void RaisePatientClicked()   -  person Eduard Dumitru    schedule 17.09.2013
comment
в основной форме например: Patient MyPatient = new Patient(); MtPatient.click += PatientClickHandler; private void PatientClichHandler(object sender,EventArgs e) { // Code } @EduardDumitru .. Моя проблема не в именах и у меня нет с ними конфликтов   -  person user2151551    schedule 17.09.2013
comment
Кто вызывает метод ProcessPatientClickedEvent? Это ключевой аспект вашей проблемы, и без этой информации мы не сможем угадать реальную проблему, с которой вы столкнулись. И, пожалуйста, подтвердите, что я правильно понял: вы хотите полностью пропустить строки кода C #, которые написаны в теле вашего вопроса? Я правильно понял?   -  person Eduard Dumitru    schedule 17.09.2013
comment
ProcessPatientClickedEvent будет вызываться отдельными элементами управления с пользовательским элементом управления пациента, состоящим из, например, если у меня есть кнопка на пользовательских элементах управления пациента, обработчиком события щелчка для этой кнопки является метод ProcessPatientClickedEvent, с чем я столкнулся, если я не реализую событие и обработчик событий в пользовательском элементе управления «Пациент», и я установил обработчик событий щелчка для каждого отдельного элемента управления в пользовательских элементах управления «Пациент», и он не сработает, а если я установлю обработчик событий щелчка для всего элемента управления из основной формы, он не сработает. Почему событие клика не запускается само по себе?   -  person user2151551    schedule 17.09.2013


Ответы (2)


UserControl наследует событие Click от класса Control. Он, конечно, может выстрелить, но это маловероятно. Вместо этого ваш пользователь будет щелкать элементы управления внутри UserControl. И он никогда не сработает, если вы покрыли всю поверхность UserControl другими элементами управления.

Вы можете просто перенаправить событие Click для собственного использования. То, с чем вы уже экспериментировали, объявив собственное событие. В этом нет необходимости, вы можете сделать это так:

private void PatientClicked()
{
    OnClick(this, EventArgs.Empty);
}

Что, как и все методы, имена которых начинаются с On и имеют то же имя, что и событие, вызывает событие Click.

person Hans Passant    schedule 17.09.2013
comment
именно то, что происходит ... Я думаю, что это ошибка .net, потому что событие щелчка по-прежнему рассматривается как событие для отдельного элемента управления, а не для всего пользовательского элемента управления. но вам необходимо повторно реализовать событие и его обработчики в классе пользовательских элементов управления. - person user2151551; 17.09.2013
comment
Возможность переопределить событие с помощью одной строчки кода - это особенность, а не ошибка. - person Hans Passant; 17.09.2013
comment
Я имею в виду, что они не учитывают весь пользовательский контроль :) - person user2151551; 18.09.2013

Я пойду и сделаю выстрел.

Допустим, у нас есть UserControl. Скажем, это выглядит примерно так:

введите описание изображения здесь

Теперь представьте, что вы написали следующие Click обработчики для 4 различных элементов управления, которые присутствуют (Button, ListView, RadioButton и сам UserControl):

public partial class UserControl1 : UserControl {

    public UserControl1() {
        InitializeComponent();
    }

    private void radioButton1_Click(object sender, EventArgs e) {
        MessageBox.Show("RadioButton");
    }
    private void listView1_Click(object sender, EventArgs e) {
        MessageBox.Show("ListView");
    }
    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("Button");
    }
    private void UserControl1_Click(object sender, EventArgs e) {
        MessageBox.Show("UserControl");
    }

}

Чтобы прояснить, о чем я говорю, проверьте это подмножество файла .designer.cs:

...
this.radioButton1.Click += new System.EventHandler(this.radioButton1_Click);
...
this.button1.Click += new System.EventHandler(this.button1_Click);
...
this.listView1.Click += new System.EventHandler(this.listView1_Click);
...
this.Click += new System.EventHandler(this.UserControl1_Click);
...

Рассмотрим следующие утверждения.

Когда вы нажимаете на эту синюю область:

введите описание изображения здесь

будет вызван обработчик UserControl1_Click, и вы увидите окно сообщения «UserControl».

Когда вы нажимаете на эту другую синюю область:

введите описание изображения здесь

будет вызван обработчик 'listView1_Click', и вы увидите, что появится окно сообщения «ListView» НО вы не увидите окно сообщения «UserControl».

Это верно для обоих оставшихся элементов управления, кнопки:

введите описание изображения здесь

и радиокнопка:

введите описание изображения здесь

Когда вы смотрите на свой UserControl с точки зрения его последнего контейнера и видите событие Click и добавляете для него обработчик событий, вы должны ожидать того же поведения, что и обработчик событий UserControl1_Click, представленный здесь.

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

public event EventHandler SmallButtonsClick {
    add {
        this.radioButton1.Click += value;
        this.button1.Click += value;
    }
    remove {
        this.radioButton1.Click -= value;
        this.button1.Click -= value;
    }
}

public event EventHandler LargeStuffClick {
    add {
        this.listView1.Click += value;
    }
    remove {
        this.listView1.Click -= value;
    }
}

или даже динамически подписать обработчик на каждый дочерний элемент управления PLUS самого UserControl:

public event EventHandler AnythingClick {
    add {
        this.Click += value;
        foreach (var child in this.Controls)
            child.Click += value;
    }
    remove {
        this.Click -= value;
        foreach (var child in this.Controls)
            child.Click -= value;
    }
}

а затем просто используйте это из окружающего мира:

UserControl1 someControl = new UserControl1();
someControl.AnythingClick += (sender, e) => MessageBox.ShowMessage("tadaaa!");
person Eduard Dumitru    schedule 17.09.2013