Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/20: Рейтинг темы: голосов - 20, средняя оценка - 4.80
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464

Прицепить делегатов в классе формы

13.11.2017, 14:55. Показов 4872. Ответов 113
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую. Начал снова учить делегатов.
Хочу сделать следующее - есть форма и 2 текстовых бокса.
При нажатии на кнопку в классе формы создаю 2 события на основании двух делегатов, в которые пойдут данные из текстбоксов.
И делаю еще класс, который должен через делегатов принять эти значения. Т.е. чтобы форма не знала об этом классе хочу добиться.
Но не могу понять, как обратиться из второго класса к моим событиям.

Код в классе формы:
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
namespace _1.Test_1
{
     public partial class frm_Main : Form
     {
          public delegate void DelegateName(string someString);
          public delegate void DelegateAge(double someDouble);
 
          public event DelegateAge GotAge;
          public event DelegateName GotName;
 
 
          public frm_Main()
          {
               InitializeComponent();
          }
 
          private void button1_Click(object sender, EventArgs e)
          {
               string name=txt_Age.Text;
               double age=Convert.ToDouble(txt_Age.Text);
 
               GotName(name);
               GotAge(age);
 
          }
     }
}
Код в классе-перехватчике:
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
namespace _1.Test_1
{
     class Controller
     {
          public void Main()
          {
               frm_Main:Form frm=new frm_Main();//Это вряд ли правильно
 
               //Тут надо подписаться на события (если я правильно это называю)
 
          }
 
          private void ShowAge(double age)
          {
               MessageBox.Show("Возраст "+age);
          }
          
          private void ShowName(string name)
          {
               MessageBox.Show("Имя "+name);
          }
 
     }
}
Миниатюры
Прицепить делегатов в классе формы  
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.11.2017, 14:55
Ответы с готовыми решениями:

С формы прицепить файл PDF в поле OLE
Подскажите, гуру access. Нужно пристегнуть файл PDF в таблицу в поле OLE. Перед этим файл с компьютера пользователя копируется...

Перетаскиванием Image c формы прицепить его к узлу дерева
Привет. Борюсь уже некоторое время с постигшей меня бедой. Никак не могу увязать Image и сабж. Нужно перетаскиванием Image c формы...

Как обращаться к компонентам формы в классе, не прописывая везде имя формы
Добрый вечер. Имеем одну форму (Class Form2), ну или две как у меня, было принято решение раскидать часть ее кода в четыре новых модуля. ...

113
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 12:14  [ТС]
Студворк — интернет-сервис помощи студентам
В классе-подписчике на событие. В блоке рекурсии. Вызывается new...вот этот момент я не понял совсем.
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 12:24
PowerCat, и что вы не поняли? Вы создаёте объект-ссылку на метод, передаёте его в метод Invoke(), а тот уже в нужный момент вызывает метод полученный по ссылке и выбрасывает ставший ненужным делегат.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 12:32  [ТС]
Ну вот это и непонятно - почему вызывается еще раз делегат? Если нет работы с инвоками, а просто подписка на событие, то никаких новых экземпляров же не создается...Подписался, указал метод обработки события - и все.
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 12:46
Цитата Сообщение от PowerCat Посмотреть сообщение
Ну вот это и непонятно - почему вызывается еще раз делегат?
Потому что метод Invoke() вызывается каждый раз, когда условие if(progressBar1.InvokeRequired) верно.

Добавлено через 30 секунд
И каждый раз создаётся новый делегат.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 13:04  [ТС]
Если не использовать несколько thread:
1. В классе-издателе создаю делегат;
2. На его основе создаю событие;
3. В нужном месте ставлю это событие и передаю ему аргумент;
4. В классе-подписчике просто указываю метод обработки.

При использовании нескольких thread:
1. В классе-издателе создаю делегат;
2. На его основе создаю событие;
3. В нужном месте ставлю это событие и передаю ему аргумент;
4. В классе-подписчике указываю метод обработки с проверкой синхронизации;
5. Проверяю синхронизацию;
6. При необходимости синхронизации делаю рекурсию.

Вот. Я вот так понимаю работу. Не могу понять только, почему в первом случае не требуется вызывать делегат в методе-обработчике, а во втором требуется. Или же в первом случае он где-то неявно спрятан?
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 13:29
PowerCat, так, кажется я догнал, что вас смутило... Не эта ли запись:

C#
1
public delegate void DelegateName(string someString);
Если она, то здесь не создаётся делегат. Здесь только объявляется его сигнатура.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 13:31  [ТС]
о!
А вот это уже интересно. Для меня именно это и было объявлением делегата. Так. Теперь надо все переосмыслить.
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 13:34
Цитата Сообщение от PowerCat Посмотреть сообщение
Для меня именно это и было объявлением делегата.
Так это оно и есть, объявление. Тоже самое, что и объявление самого класса.

Тут вы просто описываете, что в природе есть делегат с именем DelegateName ничего не возвращающий (void) и принимающий одну строку (String). А создавать их экземпляры нужно явно (new), и можно это делать в любом количестве (больше одного одновременно).
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 13:36  [ТС]
Ок. Когда нет нескольких thread - где там создается новый экземпляр делегата? Если с несколькими thread явно видно NEW, то в первом случае - нет.
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 13:47
PowerCat, экземпляры делегатов создаются там, где вы их создаёте. Это или new DelegateName(метод) или лямбды (агрументы) => тело или иная форма анонимной функции (delegate (аргументы) { тело }).

Если вы ничего не делаете, то ничего и не происходит. Объявление чего-то - это только объявление, а не принуждение к действию.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 14:22  [ТС]
Ок.
В этом примере где создается экземпляр делегата?
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
namespace Test_1
{
     class Controller
     {
          //public void Start()
          static void Main()
          {
               var frm=new frm_Main();
               frm.NameHasBeenShown+=ShowName;
 
               frm.ShowDialog();
 
          }
 
          private static string ShowName(string name)
          {
               MessageBox.Show("Имя "+name);
               return null;
          }
     }
}
namespace Test_1
{
     public partial class frm_Main : Form
     {
          public delegate string String_Delegate(string someString);
 
          public event String_Delegate NameHasBeenShown;
          
          public frm_Main()
          {
               InitializeComponent();
          }
 
 
          private void btn_ShowName_Click(object sender, EventArgs e)
          {
               SendName("Строка");
          }
 
          private string SendName(string inletText)
          {
               if(NameHasBeenShown!=null)
               {
                    NameHasBeenShown(inletText);
               }
               return null;
          }
 
     }
}
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 14:37
PowerCat, в строке №9.

Добавлено через 2 минуты
На самом деле, там даже два делегата создаётся: делегат указывающий на метод, и новый делегат как комбинация переданного и старого события (событие - делегат, вы же помните?).
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 14:55  [ТС]
Посмотрел справочник. По нему строка 9 должна быть написана так:
C#
1
frm.NameHasBeenShown+=new String_Delegate(ShowName);
Запутался полностью ))
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
30.11.2017, 15:09
PowerCat, она так и выглядит. Форма записи frm.NameHasBeenShown+=ShowName; - лишь синтаксический сахар, чисто для сокращения записи. Компилятор корректный код генерирует.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
30.11.2017, 15:11  [ТС]
ааа...ну тогда другое дело
В обоих случаях происходит создание нового экземпляра делегата.
Вот теперь все понятно. А то было там так, а тут эдак...
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
21.12.2017, 17:36  [ТС]
и опять возвращаясь к делегатам...
Да, я применил их для установки связи между threads, передал информацию...но:
1. Сделал это втемную, не особо понимая;
2. Уверен, что это лишь их побочное применение.

Нашел это обсуждение на этом же форуме. Собственно вопрос у меня полностью такой же - а зачем они собственно нужны? Почему нельзя просто сразу указать необходимый метод?
К сожалению нет объяснения "на пальцах"

Добавлено через 41 минуту
Смотрел еще вот этот пример. Так и не понял, автор вначале говорит, что если дополнять свитч, то потребуется перекомпиляция. А если использоваться делегаты - не потребуется???
Вот чисто визуально крохотный свитч занимает минимум места, по сравнению с применением делегатов.
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
21.12.2017, 18:09
PowerCat, не вижу смысла вам это объяснять. Я вам уже несколько страниц в вашей прошлой теме расписывал всё на пальцах. Если всё ещё непонятно, то значит не судьба.
0
21.12.2017, 18:33
 Комментарий модератора 
PowerCat, не надо отклоняться от темы обсуждения. В п4.4 правил не зря написано - "На каждый вопрос создавайте по одной теме". Если необходимо вернуться к обсуждению делегатов, то делайте это в в своей прошлой теме.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
21.12.2017, 18:38  [ТС]
На пальцах была техническая часть, мне же непонятна практическая... Я более чем уверен, что абсолютно ВСЕ задавали этот вопрос. Т. е. зачем применять делегат, если можно явно указать метод
0
Эксперт .NET
 Аватар для Usaga
14784 / 9558 / 1366
Регистрация: 21.01.2016
Сообщений: 36,039
21.12.2017, 18:47
PowerCat, я вам тоже этот момент объяснял: для вынесения части логики в виде настраеваемого аспекта. Мощь подхода в том, что вы не знаете, какой именно (и чей) метод вы вызываете. И сколько их вообще будет (делегат может ссылаться сразу на кучу разных методов, которые вызовет по очереди).

Array.Sort<T> - самый наглядный пример. В методе реализована только логика перебора элементов массива, но логика их сравнения вынесена из алгоритма и задаётся произвольно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.12.2017, 18:47

Обработка событий формы в классе
Я создаю библиотеку, в ней одна форма MyForm и модуль класса MyClass. В форме объявлено событие Public Event OkClicked()Событие...

Вызов объектов формы в классе
Может слегка не корректно описал вопрос. В общем есть программа и нужно в функциях класса использовать элементы формы. Unit1.cpp ...

Расположение переменных в классе формы
Есть код. { public partial class Form4 : Form { public Form4() {

Функция класса не работает в классе формы
Пытаюсь описать функцию для подсчёта суммы чисел. using System; using System.Collections.Generic; using System.ComponentModel; ...

Использование компонента формы в своем классе
Здравствуйте у меня такой вопрос, можно ли как нибудь использовать компонент формы в своем классе?


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru