Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/12: Рейтинг темы: голосов - 12, средняя оценка - 4.58
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
1

Обработчик событий

12.03.2013, 10:02. Показов 2235. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть панель с контролами, каждый контрол имеет свой номер. Есть рандомное число (int temp).
Не могу разобраться с обработчиком. Нужно чтобы по нажатию на контрол имеющий номер рандомного числа выполнялись некоторые действия. Использую конструкцию:
C#
1
this.lst[temp].Click += new System.EventHandler(this.LstTempClick);
но вылетает NullReferenceException.
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.03.2013, 10:02
Ответы с готовыми решениями:

Обработчик событий
Доброе время суток... В общем я студент... и уже конец семестра... и надо срочно ваша помощь.......

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

Один обработчик событий для нескольких объектов
Здравствуйте, подскажите пожалуйста, как так сделать? В VB.NET надо после Handler(вроде) писать, а...

Можно ли в обработчик событий передать свою переменную
Здравствуйте. Я только начинаю познавать C# и возник такой вопрос/проблема (возможно глупая)....

16
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
12.03.2013, 11:19 2
Для начала я бы посмотрел, в какой строке вылетает NullReferenceException.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 11:30 3
Цитата Сообщение от vladimir8686 Посмотреть сообщение
Есть панель с контролами, каждый контрол имеет свой номер. Есть рандомное число (int temp).
Не могу разобраться с обработчиком. Нужно чтобы по нажатию на контрол имеющий номер рандомного числа выполнялись некоторые действия. Использую конструкцию:
C#
1
this.lst[temp].Click += new System.EventHandler(this.LstTempClick);
но вылетает NullReferenceException.
Это ты подписываешься на событие, это нужно сделать 1 раз для всех контролов и можно подписаться на один обработчик, а не на кол-во обработчиков равное кол-ву контролов.

Добавлено через 48 секунд
Вообще скинь проект, быстрее будет. С нуля неохота делать.
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
12.03.2013, 11:32 4
Цитата Сообщение от vladimir8686 Посмотреть сообщение
Есть панель с контролами, каждый контрол имеет свой номер. Есть рандомное число (int temp).
Не могу разобраться с обработчиком. Нужно чтобы по нажатию на контрол имеющий номер рандомного числа выполнялись некоторые действия.
Что такое lst? Предполагаю, что всё-таки temp выходит за границы этой коллекции/массива.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 11:45 5
Цитата Сообщение от Cupko Посмотреть сообщение
Что такое lst? Предполагаю, что всё-таки temp выходит за границы этой коллекции/массива.
Судя по коду, он подписывается на событие не один раз. Короче, без проекта можно ещё на пару страниц гадать. Или кода бы больше выложил, не понятно в каком месте эта строка вообще используется.

C#
1
int m = 10;
Почему у меня виснет форма? Тоже самое.
0
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 12:16  [ТС] 6
Цитата Сообщение от ksk Посмотреть сообщение
Для начала я бы посмотрел, в какой строке вылетает NullReferenceException
Эксепшн ссылается на эту строку.

Цитата Сообщение от Cupko Посмотреть сообщение
Что такое lst?
lst - это список. Я прохожу по панельке циклом foreach и заношу все контролы в него. За границы точно не выходит.

Цитата Сообщение от Casper-SC Посмотреть сообщение
Вообще скинь проект, быстрее будет.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
namespace MiniGame1
{
    public partial class MainForm : Form
    {
        static Random r;        
        Thread t1;
        List<Control> lst;
        int temp;
        int pushed;
        int missed;
        int total;
        int efficient;
        bool anchor;
        
        public MainForm()
        {
            InitializeComponent();
            
            r = new Random();
            t1 = new Thread(MainMeth);
            lst = new List<Control>();
            anchor = false;
            
            pushed = missed = total = efficient = 0;
            
            foreach(Control c in panel1.Controls)
                lst.Add(c);
        }
            
        void MainMeth()
        {
            while(true)
            {   
                temp = r.Next(1, 130);
                lst[temp].BackgroundImage = new Bitmap (@"G:\images.jpg");
                lst[temp].BackgroundImageLayout = ImageLayout.Stretch;
                anchor = true;
                Thread.Sleep(1550);
                lst[temp].BackgroundImage = null;
                lst[temp].BackColor = SystemColors.ActiveCaption;
                anchor = false;
                total ++;                   
            }
        }
        this.lst[temp].Click += new System.EventHandler(this.LstTempClick);
        // LstClick
        void LstTempClick(object sender, EventArgs e)
        {
            pushed ++;
            Count_zero.Text = Convert.ToString(pushed);
        }
        
        void StartToolStripMenuItemClick(object sender, EventArgs e)
        {   
            t1.IsBackground = true;
            t1.Start();
        }
    }
Описание: панель с кномпками, генерируется случайное число, на кнопке этого номера показывается картинка, нужно успеть на нее кликнуть, счетчик увеличивается на 1 если игрок успел кликнуть. Вот собственно этот клик мне и нужен. Anchor для проверки есть ли картинка на кнопке или нет. Остальные переменные роли не играют.

Добавлено через 11 минут
Строку
C#
1
this.lst[temp].Click += new System.EventHandler(this.LstTempClick);
я вставлял в generated code что создает вижуал студиа, здесь в таком виде выдает просто как синтактические ошибки.
1
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 12:38 7
Скинь сам проект.
0
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 12:55  [ТС] 8
Аттачед.
... и небольшое пожелание если можно.
Можно с комментариями или просто примерно объяснить что где не так и как реализовать? Просто если юзать готовый чужой код, далеко так не уйдешь.
Вложения
Тип файла: zip MiniGame1.zip (971.3 Кб, 4 просмотров)
1
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 13:10 9
Понятно всё. Проект явно не ты делал, правильно я понимаю? Ща должно заработать.

Вот эту строку ты вообще запихал не пойми куда и не пойми зачем. Впечатление, что ты вообще ничего не понимаешь .
C#
1
this.lst[temp].Click += new System.EventHandler(this.LstTempClick);
Добавлено через 34 секунды
Ща скину вариант рабочий, только картинки сам сделаешь, я тупо буду фон менять у кнопки.

Добавлено через 6 минут
И тебе принципиально нужен поток? Может на таймер проще переделать?
0
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 13:25  [ТС] 10
Цитата Сообщение от Casper-SC Посмотреть сообщение
Понятно всё. Проект явно не ты делал, правильно я понимаю
Если это комплимент, то комплимент засчитан)) Я новичек и у меня пока не совсем лады с делегатами/событиями.
Приложение мое, все события я генерирую двойным нажатием по контролу, а это не мог сгенерировать, поэтому написал его сам глядя на другие события и засунул его просто где находятся другие, и самое главное что работало, только не совсем как надо.
Вообщем, мне бы конечно лучше разъяснить где подправить, чем выкладывать новый проект, я их делаю для себя для практики, а не для коллекционирования.
1
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 13:25 11
Короче, как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
 
namespace MiniGame1
{
    public partial class MainForm : Form
    {
        #region Fields
 
        private bool _exit;
        static Random _random;
        Thread _thread;
        List<Control> _controls;
        int _index, pushed, _missed, _total, efficient;
        #endregion
 
        public MainForm()
        {
            InitializeComponent();
            StartPosition = FormStartPosition.CenterScreen; //почему вообще все это игнорят?
 
            _exit = false;
            _random = new Random();
            _thread = new Thread(MainMeth);
            _controls = new List<Control>();
 
            pushed = _missed = _total = efficient = 0;
 
            foreach (Control c in panel1.Controls)
                _controls.Add(c);
        }
 
        private void MainForm_Shown(object sender, EventArgs e)
        {
            _thread.Start();
        }
 
        void StartToolStripMenuItemClick(object sender, EventArgs e)
        {
            _thread.IsBackground = true;
            _thread.Start();
        }
 
        void CloseToolStripMenuItemClick(object sender, EventArgs e)
        {
            Close();
        }
 
        void MainFormFormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = MessageBox.Show("Really?", "Quit", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                e.Cancel = false;
                _exit = true;
            }
            else
                e.Cancel = true;
        }
 
        void MainMeth()
        {
            while (!_exit)
            {
                _index = _random.Next(1, 130);
                 Invoke((Action)delegate
                    {
                        _controls[_index].BackColor = Color.DarkRed;
                        _controls[_index].BackgroundImageLayout = ImageLayout.Stretch;
                        _controls[_index].Click += new EventHandler(LstTempClick);            
                    });
 
                Thread.Sleep(1550);
 
                if (_exit)
                   break; 
                
                Invoke((Action)delegate
                {
                    _controls[_index].Click -= new EventHandler(LstTempClick);
                    _controls[_index].BackColor = SystemColors.ActiveCaption;
                });
 
                _total++;
                _missed = _total - pushed;
                Invoke((Action) delegate
                {
                    Missed_count.Text = Convert.ToString(_missed);
                });
            }
        }
 
        // LstClick
        void LstTempClick(object sender, EventArgs e)
        {
            pushed++;
            Count_zero.Text = Convert.ToString(pushed);
        }
    }
}
Вложения
Тип файла: zip MiniGame1.zip (620.4 Кб, 6 просмотров)
1
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 13:27 12
Цитата Сообщение от vladimir8686 Посмотреть сообщение
Вообщем, мне бы конечно лучше разъяснить где подправить, чем выкладывать новый проект, я их делаю для себя для практики, а не для коллекционирования.
Ну я то твой код поправил просто. Да комментировать там много надо, это сидеть ещё пол часа выдумывать.
0
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 16:04  [ТС] 13
Спасибо! Прям то что нужно! Ничего там комментировать не нужно, и так все понятно. Я знал, что нужно invoke использовать, но не знал как. Тяжело мне пока делегаты даются. Вообщем, спасибо!

Добавлено через 1 час 1 минуту
Проанализировал код внимательно.
Вся моя ошибка была только в использовании ключевого слова this в подписке на событие, и изначально я ее правильно разметил, пока в соседней теме, один гений мне не подсказал ее вынести.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 16:10 14
Цитата Сообщение от vladimir8686 Посмотреть сообщение
Проанализировал код внимательно.
Вся моя ошибка была только в использовании ключевого слова this в подписке на событие, и изначально я ее правильно разметил, пока в соседней теме, один гений мне не подсказал ее вынести.
После того как с кнопки пропадает картинка (или цвет меняется на стандартный) нужно отписываться от обработчика события, иначе при следующем нажатии на неё всё равно засчитается попадание по картинке, а когда эта кнопка снова получит картинку, то она подпишется ещё раз на тот же обработчик и уже нажатие на кнопке 2 раза вызовет обработчик и засчитает 2 очка. Это если оставить так, как было до моего редактирования (закоментирована строка была).

Добавлено через 1 минуту
Цитата Сообщение от Casper-SC Посмотреть сообщение
_thread.IsBackground = true;
Это вообще надо вынести туда где инициализируется поток, а не вызывать вместе с _thread.Start();

Добавлено через 1 минуту
Мне почему-то кажется, что здесь разумнее таймер использовать.
1
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 17:08  [ТС] 15
Спасибо за замечания, все поправил. С таймером никогда не работал, и пока не представляю, что это. Сейчас погуглю. Есть одна проблемка, если успеваешь кликнуть несколько раз на картинке, то счетчик увеличится не на один раз, а на кол-во кликов.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
12.03.2013, 17:34 16
C#
1
2
3
4
5
6
        void LstTempClick(object sender, EventArgs e)
        {
            ((Button)sender).Click -= new EventHandler(LstTempClick); // <<<<<<<<<<
            pushed++;
            Count_zero.Text = pushed.ToString(); // Можно ещё так в строку конвертировать, даже нужно
        }
Добавлено через 2 минуты
Конкретно в этом названии метода вообще не вижу причин для таких сокращений:
LstTempClick, не лучше ли ListTempClick (если я правильно понял сокращённое слово). И вообще все эти: r, t1 режут глаз.
1
36 / 36 / 4
Регистрация: 27.05.2012
Сообщений: 180
Записей в блоге: 5
12.03.2013, 18:05  [ТС] 17
Класс! Спасибо! По поводу сокращений, я учился по видеокурсу Гудка, а он все названия сокращает: list = lst, button = btn, control = ctrl и т.д. Ну я и подумал, что так принято в среде программирования, как например интерфейсы начинать с буквы I.
0
12.03.2013, 18:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.03.2013, 18:05
Помогаю со студенческими работами здесь

Можно ли как-нибудь обработчик событий сделать через цикл ?
for (int i = 0; i &lt; button.Length; i++) { this.button = new Button();...

Как передать массив объектов как параметр в обработчик событий
Добрый вечер. Возник вопрос, как правильно передать массив объектов как параметр в обработчик...

Реализовать хранилище событий, для хранения событий в БД
Доброго дня! Поставлена задача реализовать хранилище событий, для хранения событий в БД) Событие...

Задачи на использование событий. Осуществить использование событий в программе с применением синтаксиса обработчика, рекомендованного для среды NET Fr
NET Framework. Программа для поиска простых чисел среди чисел Фибоначчи. При нахождении...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru