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

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

13.11.2017, 14:55. Показов 5049. Ответов 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
20.11.2017, 14:36  [ТС]
Студворк — интернет-сервис помощи студентам
Ну вот именно так я делаю, обзывая это бубличное событие кастомным.
Т.е. Sender, EventHandler - это только для "внутри класса формы"?
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
20.11.2017, 14:42
PowerCat, нет. Вообще никакой связи с областью видимости у этих делегатов нет, от слова "совсем". Кнопка - деталь реализации класса формы. Внешний код об этом знать не должен.

Чисто технически, вы можете сделать кнопку публичной и получить к ней доступ извне класса формы, но это категорическое "фу".
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
20.11.2017, 15:25  [ТС]
Согласен полностью.
Благодарю за пояснения, оказывается, что шел правильным путем ))
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 13:04  [ТС]
Событие не видит свой обработчик в слушающем классе (возвращает null).

Класс слушающий:
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
 
namespace Friction_Factor
{
     public class Core
     {
          //--Поля--//
 
 
          //--Подписка--//
          public void Subscribe()
          {
               Controller.ReadyForCore+=Index;
               
          }
 
          private void Index(string string_1,
                             string string_2,
                             string string_3,
                             string string_4,
                             List<string> list_1,
                             List<double> list_2,
                             double double_1)
          {
 
          }
 
     }
}
Класс транслирующий
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
 
using unvell.ReoGrid;
using unvell.ReoGrid.CellTypes;
using unvell.ReoGrid.Actions;
using unvell.ReoGrid.DataFormat;
 
namespace Friction_Factor
{
     static class Controller
     {
 
          public delegate void delegate_4String_2List_Double(string string_1,
                                                             string string_2,
                                                             string string_3,
                                                             string string_4,
                                                             List<string> list_1,
                                                             List<double> list_2,
                                                             double double_1);
 
          public static event delegate_4String_2List_Double ReadyForCore;//--Подготовка данных для ядра выполнена--//
          
          [STAThread]
          static void Main()
          {
               var form=new frm_Main();
               Application.Run(form);
          }
 
 
          private static void Run(string pathToBpn,string errorFromForm,ReoGridControl gridControl)
          {
               if(ReadyForCore!=null)
               {
                    ReadyForCore("111", "111", "111", "111", new List<string>{"1"}, new List<double>{1}, 2);
               }
          }
     }
}
При этом, если я подписываю класс формы на это событие, она его обрабатывает
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 13:12
PowerCat, а метод Subscibe() кто будет вызывать?
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 13:14  [ТС]
хм...интересный вопрос..
я полагал, что слушающий класс начинает работу в момент, когда ловит событие...
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 13:15
А код - ужас.

Заверните все аргументы в отдельный класс, не нужно всю эту портянку перечислять в аргументах. Используйте стандарные делегаты (Action<>, Function<>), не надо на каждый чих выдумывать свой (delegate_4String_2List_Double). Откуда такая тяга к статическим методам? Вы на Си, что ли, пишите?

Добавлено через 41 секунду
Цитата Сообщение от PowerCat Посмотреть сообщение
я полагал, что слушающий класс начинает работу в момент, когда ловит событие...
Вы не создали экземпляр своего "слушающего" класса и не подписали его. Некому слушать.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 13:19  [ТС]
Статический метод - он стартовый, переименованный Program, отсюда все его методы статические. Да и используется он разово, экземпляры не нужны.

Мне проще написать значимое имя делегата, чем потом гадать...

Аргументы в отдельный класс - хм, как-то в голову не приходило...Сделать их полями отдельного класса?

На C#

Добавлено через 2 минуты
Цитата Сообщение от Usaga Посмотреть сообщение
Вы не создали экземпляр своего "слушающего" класса и не подписали его. Некому слушать.
аа...точно, вот я туплю )) форма-то создана...
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 13:22
Цитата Сообщение от PowerCat Посмотреть сообщение
Мне проще написать значимое имя делегата, чем потом гадать...
Вам надо сделать имя события говорящим. Имя делегата вообще роли не играет.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 13:24  [ТС]
У меня почти всегда имена всего говорящие ))) не важно, что называю ))

Я поизучал Троелсена, лямбда-выражения, обобщенные делегаты...так и не понял - а зачем? Исключительно ради сокращения кода?
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 13:26
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
class Class
{
    public event Action<string> UserRegistered = delegate { }; // Вполне себе понятно о чём это
 
    public void RegisterUser(string login)
    {
        UserRegistered(login);
    }
}
 
class Consumer
{
    public Consumer()
    {
        var cl = new Class();
 
        cl.UserRegistered += OnUserRegistered;
    }
 
    private void OnUserRegistered(string login)
    {
        // Что-то сделать с логином
    }
}
Добавлено через 1 минуту
Цитата Сообщение от PowerCat Посмотреть сообщение
Я поизучал Троелсена, лямбда-выражения, обобщенные делегаты...так и не понял - а зачем? Исключительно ради сокращения кода?
Да, для сокращения. Чтобы код был кратким и ясным.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 13:30  [ТС]
Я понимаю, что так можно написать и сократить код. НО - мне проще явно все описывать, чтобы через полгода не ужасаться, что же тут такое было ))

Добавлено через 1 минуту
Цитата Сообщение от Usaga Посмотреть сообщение
Да, для сокращения. Чтобы код был кратким и ясным.
Таким в подобной нотации он становится для тех, кто програмит каждый день и привыкает к подобной записи. Для таких же, как я, кто пишет от случая к случаю - гораздо удобнее все явно писать ))

Добавлено через 2 минуты
Цитата Сообщение от Usaga Посмотреть сообщение
Заверните все аргументы в отдельный класс, не нужно всю эту портянку перечислять в аргументах
Сделать полями класса? Потом выдергивать через экземпляр?
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 13:33
Цитата Сообщение от PowerCat Посмотреть сообщение
Я понимаю, что так можно написать и сократить код. НО - мне проще явно все описывать, чтобы через полгода не ужасаться, что же тут такое было ))
Можете и так. Чем оно более явнее и говорящее, тем лучше.

Цитата Сообщение от PowerCat Посмотреть сообщение
Сделать полями класса? Потом выдергивать через экземпляр?
Сделайте отдельный класс со свойствами, без логики. Чисто для передачи данных. Это называется DTO - Data Transfer Object.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 14:49  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Сделайте отдельный класс со свойствами, без логики. Чисто для передачи данных. Это называется DTO - Data Transfer Object.
Интересное решение...Благодарю за подсказки )

Добавлено через 1 час 12 минут
Цитата Сообщение от Usaga Посмотреть сообщение
Сделайте отдельный класс со свойствами, без логики. Чисто для передачи данных. Это называется DTO - Data Transfer Object.
Вот тут немного непонятно.
Если сделать обычный класс, то для доступа к данным, "хранящимся" в нем, придется передавать между методами/классами ссылку на экземпляр, в которую все смогут что-нибудь класть. Я правильно понимаю идею? Т.е. вместо "портянки" аргументов - всегда только один аргумент?
Или же надо делать статик класс, чтобы просто ссылаться на него, безэкземплярно?
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 16:12
PowerCat, создаёте класс, наполняете, передаёте. Если не хотите, чтобы после создания его содержимое изменялось, то сделайте его свойства доступными только для чтения. Слово "статик" забудьте.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 16:39  [ТС]
Передавать ссылкой на наполненный экземпляр класса?
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 17:14
Да.
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 17:23  [ТС]
Понятно.
Еще вопрос - как вот это модернизировать, чтобы воспользоваться Action? Тут же указывается делегат в явном виде.

C#
1
2
3
4
5
6
7
8
9
10
11
          private static void SetProgressBar(int counter)
          {
               if(pBar.InvokeRequired)
               {
                    pBar.Invoke(new HeavyProcess.Long_Delegate(SetProgressBar), counter);
               }
               else
               {
                    pBar.Value=counter*10;
               }
          }
0
Эксперт .NET
 Аватар для Usaga
14819 / 9598 / 1369
Регистрация: 21.01.2016
Сообщений: 36,146
23.11.2017, 18:30
PowerCat,
C#
1
2
3
4
5
6
7
8
9
10
11
          private static void SetProgressBar(int counter)
          {
               if(pBar.InvokeRequired)
               {
                    pBar.Invoke(new Action(() => SetProgressBar(counter));
               }
               else
               {
                    pBar.Value=counter*10;
               }
          }
0
 Аватар для PowerCat
0 / 2 / 1
Регистрация: 19.09.2013
Сообщений: 464
23.11.2017, 20:22  [ТС]
хм...завтра буду пробовать, благодарю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.11.2017, 20:22

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru