Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
646 / 474 / 38
Регистрация: 04.11.2013
Сообщений: 1,949
1

Единый обработчик событий для нескольких схожих элементов

17.01.2014, 21:36. Показов 4950. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть 15 ТекстБоксов с именами TB1 .... TB15. Можно ли сделать единый обработчик события TextChanged для них по типу:
VB.NET
1
Private Sub TB_TextChanged(sender As System.Object, e As System.EventArgs) Handles TB(1-15).TextChanged
TB(1-15) это, конечно, бред. Но фантазия и куцые знания пасуют..
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2014, 21:36
Ответы с готовыми решениями:

Один обработчик событий для нескольких разных элементов
Суть в следующем: Есть несколько TextBox, По у молчанию в них записан одинаковый текст. Как...

Обработчик событий для нескольких кнопок
Доброго времени суток! У меня есть toolStrip, и на нём есть кнопка, по нажатию этой кнопки,...

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

Обработчик событий для нескольких компонентов
В моей программе есть несколько компонентов TEdit, а так же StringGrid. Суть в том, чтобы...

17
356 / 295 / 78
Регистрация: 02.10.2013
Сообщений: 476
Записей в блоге: 5
17.01.2014, 22:01 2
Да
VB.NET
1
2
3
4
 Dim tbArr(14) As TextBox
        For i = 0 To 14
            AddHandler tbArr(i).Click, AddressOf tbArr_Click ' где tbArr_Click имя процедуры обработчика
        Next
2
Форумчанин.NET
555 / 426 / 64
Регистрация: 12.02.2013
Сообщений: 834
17.01.2014, 22:08 3
Лучший ответ Сообщение было отмечено как решение

Решение

VB.NET
1
Private Sub TB_TextChanged(sender As System.Object, e As System.EventArgs) Handles TB1.TextChanged, B2.TextChanged, B3.TextChanged, B4.TextChanged
3
Почетный модератор
21415 / 9150 / 1083
Регистрация: 11.04.2010
Сообщений: 11,014
17.01.2014, 22:33 4
Лучший ответ Сообщение было отмечено как решение

Решение

Если поля уже на форме, то
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        For I As Integer = 1 To 15
            AddHandler CType(Controls("TB" & I), TextBox).TextChanged, AddressOf TxtChange
            Controls("TB" & I).BackColor = Color.LightPink
        Next
    End Sub
 
    Sub TxtChange(ByVal sender As TextBox, ByVal e As System.EventArgs)
        If sender.TextLength > 0 Then
            sender.BackColor = Color.LightGreen
        Else
            sender.BackColor = Color.LightPink
        End If
    End Sub
4
646 / 474 / 38
Регистрация: 04.11.2013
Сообщений: 1,949
17.01.2014, 22:34  [ТС] 5
Здорово! А можно каким-нибудь из этих методов еще и отследить, какой именно текстбокс сработал (получить его номер?)? (Без кучи операторов if...)
0
Почетный модератор
21415 / 9150 / 1083
Регистрация: 11.04.2010
Сообщений: 11,014
17.01.2014, 22:41 6
Proidoha, в моем посте это реализовано
1
646 / 474 / 38
Регистрация: 04.11.2013
Сообщений: 1,949
18.01.2014, 00:46  [ТС] 7
Памирыч, Вижу, спасибо.

Добавлено через 7 минут
Вобщем, все работает. Единственная проблема - у меня текстбоксы внутри группбокса (я как полнейший юзер использовал группбокс в качестве обычной рамочки). А внутри группбокса этот код не работает, мало того - доходит до строчки AddHandler CType ...... и выбрасывает из обработчика MyBase.Load
Пошел читать про группбоксы.
0
Почетный модератор
21415 / 9150 / 1083
Регистрация: 11.04.2010
Сообщений: 11,014
18.01.2014, 00:48 8
Proidoha, все верно, работать не будет.
Controls("TB" & I) - для формы
Полное оформление - Me.Controls("TB" & I)
Я должен был это пистаь целиком, Вы бы сразу поняли, что фишка в Me.
VB.NET
1
Controls("TB" & I)

замените на
VB.NET
1
GroupBox1.Controls("TB" & I)
3
0 / 0 / 0
Регистрация: 09.01.2015
Сообщений: 20
23.03.2019, 18:59 9
Здравствуйте, Андрей.
5 лет назад Вы писали об одном обработчике событий, но события из другого контейнера нужно было прописывать отдельной строкой с указанием имени контейнера.
У меня сотни кнопок и около 30 контейнеров. Все кнопки в контейнерах с оригинальными (не повторяющимися) названиями + кнопки на самой форме.
Как можно написать строки:
k(x) = Controls("Button" & x) и k(x) = GroupBox1.Controls("Button" & x) и так далее, чтобы потом адресовать на обработчик строкой
AddHandler k(x).Click, AddressOf k_Click

Пытался менять признак Modifiers и у кнопок и у контейнеров, но из формы система эти кнопки всё равно не видит и нет возможности прописать обработчик о одном цикле((

Как сделать, чтобы не писать циклы для каждого контейнера?

Спасибо!
0
Администратор
Эксперт .NET
17689 / 13817 / 5310
Регистрация: 17.03.2014
Сообщений: 28,326
Записей в блоге: 1
23.03.2019, 21:22 10
Цитата Сообщение от serg_br Посмотреть сообщение
Как сделать, чтобы не писать циклы для каждого контейнера?
Разные варианты можно применить. Использовать Controls.Find который умеет искать элементы во вложенных контейнерах. Этот способ будет медленно работать для большого количества элементов управления. Можно перечислить все контейнеры в какой-либо коллекции и сделать один цикл по ней. Наконец можно сделать метод который рекурсивно переберет все элементы на форме.

Для конкретного примера нужно знать как именно устроена формы. Сколько контейнеров и какие они. Глубина их вложенности (текущая/планируемая). Есть ли другие кнопки на форме на которые не нужно вешать обработчик.

Цитата Сообщение от serg_br Посмотреть сообщение
Пытался менять признак Modifiers и у кнопок и у контейнеров,
Модификатор доступа регулирует доступ из других классов. На код внутри формы он никак не влияет.
1
0 / 0 / 0
Регистрация: 09.01.2015
Сообщений: 20
27.03.2019, 23:25 11
OwenGlendower,
Максимальная глубина вложенности 2, то есть всего 3 уровня.
Мне представляется более интересным реализовать перечисление контейнеров в коллекцию и сделать один цикл.
Если не сложно, напишите пожалуйста, как будет выглядеть код для объединения в коллекцию?
Какие особенности при обращении к ней в цикле?
Спасибо.
0
Администратор
Эксперт .NET
17689 / 13817 / 5310
Регистрация: 17.03.2014
Сообщений: 28,326
Записей в блоге: 1
28.03.2019, 02:01 12
serg_br, можно использовать следующую функцию перебора всех дочерних элементов
VB.NET
1
2
3
4
5
6
7
8
Iterator Function AllControls(control As Control) As IEnumerable(Of Control)
    For Each childCtrl In control.Controls
        Yield childCtrl
        For Each grandChildCtrl In AllControls(childCtrl)
            Yield grandChildCtrl
        Next
    Next
End Function
Чтобы найти все кнопки пишем следующий цикл
VB.NET
1
2
3
For Each c In AllControls(Me).OfType(Of Button)()
    ...
Next
3
0 / 0 / 0
Регистрация: 09.01.2015
Сообщений: 20
29.03.2019, 22:58 13
OwenGlendower
Интегрировать код не получается, что-то не так с синтаксисом:
VB.NET
1
2
3
4
5
6
7
8
Iterator Function AllControls(control As Control) As IEnumerable(Of Control)
    For Each childCtrl In control.Controls
        Yield childCtrl
        For Each grandChildCtrl In AllControls(childCtrl)
            Yield grandChildCtrl
        Next
    Next
End Function
Не понимает "Intertator" - требует объявления
Аналогично не принимает Yield

PS А как будет выглядеть сбор в коллекцию?
0
Администратор
Эксперт .NET
17689 / 13817 / 5310
Регистрация: 17.03.2014
Сообщений: 28,326
Записей в блоге: 1
29.03.2019, 23:16 14
serg_br, какая у тебя версия VS?
0
0 / 0 / 0
Регистрация: 09.01.2015
Сообщений: 20
29.03.2019, 23:51 15
OwenGlendower, у меня Express версия vb.net 2010
0
Администратор
Эксперт .NET
17689 / 13817 / 5310
Регистрация: 17.03.2014
Сообщений: 28,326
Записей в блоге: 1
30.03.2019, 00:34 16
serg_br, ясно. Итераторы доступны в VS 2012 и выше. В таком случае сделаем без них. Добавляем в проект новый модуль
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Imports System.Runtime.CompilerServices
 
Module ControlExtensions
 
    <Extension()> _
    Public Function GetAllControls(ctrl As Control) As Control()
        Dim controls As New List(Of Control)
        InnerGetAllControls(ctrl, controls)
        Return controls.ToArray()
    End Function
 
    Private Sub InnerGetAllControls(ctrl As Control, controls As List(Of Control))
        For Each childCtrl As Control In ctrl.Controls
            controls.Add(childCtrl)
            InnerGetAllControls(childCtrl, controls)
        Next
    End Sub
 
End Module
И пользуемся
VB.NET
1
2
3
For Each btn In Me.GetAllControls().OfType(Of Button)()
    ...
Next
1
Модератор
Эксперт .NET
4314 / 3388 / 507
Регистрация: 27.01.2014
Сообщений: 6,186
30.03.2019, 07:17 17
OwenGlendower, очень красиво выглядят оба варианта
0
0 / 0 / 0
Регистрация: 09.01.2015
Сообщений: 20
31.03.2019, 02:07 18
OwenGlendower, большое спасибо, работает!
У меня оказалось на одну вложенность глубже. Я еще не изучил структуру vb.net, не выхожу за рамки класса и не привык применять не полностью понятный для меня код,- написал всё "своим языком". Получилось немного по-детски, но работает))

Добавлено через 1 час 19 минут
OwenGlendower, Yury Komar, вот что у меня получилось.
Может быть кому-нибудь пригодится

VB.NET
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
Dim MenuKey(2000) As Button 'для индексов рабочих кнопок
Dim x As Integer 'временная, для работы с номерами кнопок
 
For Each btn As Control In Controls 'перебор объектов 0 уровня
            If TypeOf btn Is GroupBox Then 'если контейнер - входим в него
                For Each btn1 As Control In btn.Controls 'пребор объектов второго уровня
                    If TypeOf btn1 Is GroupBox Then 'если контейрей - входим в него
                        For Each btn2 As Control In btn1.Controls 'перебор объектов 3 уровня
                            If LSet(btn2.Name, 6) = "Button" Then 'проверяем, что имя нужных кнопок (на уровне 3) и
                                BtnSave(btn2) 'уходим в процедуру привязки к индексу и адресацию обработки нажания
                            End If
                Next
                    ElseIf LSet(btn1.Name, 6) = "Button" Then 'проверяем, что имя нужных кнопок (на уровне 2) и
                        BtnSave(btn1) 'уходим в процедуру привязки к индексу и адресацию обработки нажания
                    End If
                Next
                'на главной форме нет нужных кнопок 
            End If
        Next
     End Sub
 
    Private Sub BtnSave(ByVal BtnIn)
        x = CInt(Mid(BtnIn.Name, 7)) 'из имени выделяем номер кнопки
        If x >= 51 Then 'у кнопок с меньшими номерами другие функции 
            MenuKey(x) = BtnIn 'приравниваем к массиву для удобства обращения, как в VB6 ))
            MenuKey(x).Text = 0 'устанавливаем числовое значение
            AddHandler MenuKey(x).MouseDown, AddressOf key_MouseDown 'прописываем обработку нажатия
        End If
    End Sub
0
31.03.2019, 02:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.03.2019, 02:07
Помогаю со студенческими работами здесь

Один обработчик событий для нескольких кнопок
Подскажите как создать один обработчик для нескольких кнопок?У меня на листе ехсеl есть 2 кнопки...

Обработчик событий нескольких контролов?
Вообще-то я программирую на Delphi, а тут понадобилось сделать проект на VBA в Excel и...

Как задать обработчик событий для элементов меню c++ WinAPI?
Как задать обработчик событий для элементов меню c++ WinAPI, что бы при выборе определенного пункта...

Единый обработчик события для разных label
Я только начал писать на C# и сразу возник вопрос, можно ли сделать так чтобы не прописывать...

Единый обработчик для Button и по нажатию с клавиатуры определённой кнопки
Здравствуйте, у меня такой вопрос. В приложении есть кнопка Button1, и я хочу по нажатию с...

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


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

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