Установка события для объекта в массиве с #

(В названии может быть ужасная формулировка)

У меня есть массив меток, я хочу добавить ввод мыши и оставить события на этих метках.

Эти ярлыки создаются программно:

            Label [] lblData = new Label[255];
        int calcLoc = 0;
        for (int i = 0; i <= 200; i++)
        {
            calcLoc = 25 * i;
            lblData[i] = new Label();
            lblData[i].Location = new Point(10, calcLoc);
            lblData[i].Text = "Test " + i;
            InfoPanel.Controls.Add(lblData[i]);

        }

Что я пробовал: Установка события в цикле (явно не сработало)

lblData[i].MouseEnter += (sender, e) => {lblData[i].BackColor = Color.LightBlue;};

Установка события перед циклом (подумал, что у этого может быть шанс)

lblData[].MouseEnter += (sender, e) => {lblData[].BackColor = Color.LightBlue;};

Ни работать.

Почему «явно не сработает» ??

Enigmativity 02.05.2018 05:10

Это WindowsForm или WPF?

Gaurang Dave 02.05.2018 05:12

Я предполагаю, что каждый берет ссылку на i, поэтому получает последнее значение i. Верно? Вы можете либо взять локальную копию i в цикле (например, var j = i;), либо объявить метод для обработки события и распаковать sender обратно в объект метки.

Llama 02.05.2018 05:15

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

Slai 02.05.2018 05:22

@Slai Я добавил код для единственного обработчика событий для всех элементов управления. Однако не могу говорить о большом количестве элементов управления.

Zer0 02.05.2018 05:29
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как насчет этого?

Label[] lblData = new Label[255];
int calcLoc = 0;
for (int i = 0; i <= 200; i++)
{
    calcLoc = 25 * i;
    Label label = new Label();
    label.Location = new Point(10, calcLoc);
    label.Text = "Test " + i;
    label.MouseEnter += (sender, e) =>
    {
        label.BackColor = Color.LightBlue;
    };
    InfoPanel.Controls.Add(label);
    lblData[i] = label;
}

Или даже это:

Label[] lblData =
    Enumerable
        .Range(0, 201)
        .Select(i =>
        {
            var calcLoc = 25 * i;
            Label label = new Label();
            label.Location = new Point(10, calcLoc);
            label.Text = "Test " + i;
            label.MouseEnter += (sender, e) =>
            {
                label.BackColor = Color.LightBlue;
            };
            InfoPanel.Controls.Add(label);
            return label;
        })
        .ToArray();
Ответ принят как подходящий

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

lblData[i].MouseEnter += (sender, e) => {((Label)sender).BackColor = Color.LightBlue;};

Более безопасная и немного более быстрая версия, на которую все экземпляры Label могут подписаться ниже.

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

private static void label_MouseEnter(object sender, EventArgs e)
{
   var label = sender as Label;
   if (label == null)
      return;
   label.BackColor = Color.LightBlue;
}

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

Zer0 02.05.2018 05:54

Из всех советов это решение сработало для меня лучше всего, поэтому оно было помечено как правильное. У меня не было проблем, и я работал немного быстрее, чем ожидал. Спасибо за помощь!

user8785416 02.05.2018 19:04

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

Zer0 03.05.2018 12:09

Другие вопросы по теме