C # Действие нажатия кнопки, чтобы заменить все остальные?

#c# #event-handling #action #buttonclick

#c# #обработка событий #Экшен #нажатие кнопки

Вопрос:

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

 button1.Click = MessageBox.Show("Run just this!"); //Yes, the '=' instead of the ' ='.
  

Это потому, что у button1 уже есть несколько событий нажатия, и я хочу, в определенной ситуации, перезаписать все остальные.

Другие примеры:

 button1.Click  = MessageBox.Show("Event #1 has been triggered!");
button1.Click  = MessageBox.Show("Event #2 and #1 have been triggered!");
button1.Click = MessageBox.Show("Event #3, and only #3, has been triggered!");
  

Ответ №1:

вы можете попробовать это…

на форумах MSDN есть решение. Приведенный ниже пример кода удалит все Click события из button1 .

вы можете сохранить одно событие на кнопке …..

 public partial class Form1 : Form
{
        public Form1()
        {
            InitializeComponent();

            button1.Click  = button1_Click;
            button1.Click  = button1_Click2;
            button2.Click  = button2_Click;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello");
        }

        private void button1_Click2(object sender, EventArgs e)
        {
            MessageBox.Show("World");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            RemoveClickEvent(button1);
        }

        private void RemoveClickEvent(Button b)
        {
            FieldInfo f1 = typeof(Control).GetField("EventClick", 
                BindingFlags.Static | BindingFlags.NonPublic);
            object obj = f1.GetValue(b);
            PropertyInfo pi = b.GetType().GetProperty("Events",  
                BindingFlags.NonPublic | BindingFlags.Instance);
            EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
            list.RemoveHandler(obj, list[obj]);
        }
    }
}
  

Комментарии:

1. Разве первое получаемое значение (для статического ключа) не должно передавать значение null?

2. Это будет работать, но нарушает множество принципов проектирования. Я советую OP не использовать этот подход, а вместо этого переосмыслить, как они подписываются. В частности: вещи, о которых вы не знаете, могут быть отменены при выполнении этого.

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

Ответ №2:

По замыслу вы обычно не можете отменить подписку на других абонентов. Это потому, что они не ваша забота. Вы могли бы использовать отражение, чтобы обойти это, но это почти наверняка список обработчиков событий, настолько нетривиальный. Если вы классифицируете элемент управления в США, вы могли бы переопределить OnClick для этого, но это все еще кажется… антисоциальный.

Если вы подписываетесь на все это, вы можете просто … не подписывайтесь на то, что вы не хотите запускать.