Страницы: 1
RSS
Обработка событий в классе (динамические элементы формы), Обработка событий в классе (динамические элементы формы)
 
Добрый день.

Возникла необходимость динамически создавать различные контролы на форме и обрабатывать события.

На примере listbox:

Создан класс clControlEvents:
Код
Option Explicit
Public WithEvents ctrl As MSForms.ListBox
'Public Event Click()
'Public Event Change()
'Public Event DblClick(ByVal Cancel As MSForms.ReturnBoolean)

Private Sub ctrl_Change()
    MsgBox ctrl.name & " change"
End Sub

Private Sub ctrl_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    MsgBox ctrl.name & " DblClic"
End Sub

Public Sub ctrl_Click()
    MsgBox ctrl.name & " Click"
End Sub

Public Sub CreateListBox(owner As MSForms.Control)
    Set ctrl = owner.Controls.Add("Forms.ListBox.1")
End Sub
В основном модуле элементы добавляются на форму так:
Код
Dim lbEvent As clControlEvents
Set lbEvent = New clControlEvents
lbEvent.CreateListBox p

Проблема в том, что события ctrl_Change, ctrl_DblClick, ctrl_Click никогда не возникают

Подскажите, что я упускаю?
 
Цитата
katep написал:
Public Sub CreateListBox(owner As MSForms.Control)
   Set ctrl = owner.Controls.Add("Forms.ListBox.1")
End Sub
это где у Вас такое записано? owner здесь что? Это указание на форму, в которой создавать листбокс? Или что это?
Вы бы приложили свой файл с кодами, чтобы другие не гадали насчет загадочных строк, значение которых приведенными кодами не понять.
Плюс Вы уверены, что элемент ListBox, созданный таким образом вообще содержит такие события? Как Вы эти события в класс добавляли? У Вас хоть одна форма создана в файле вообще?
Изменено: Дмитрий(The_Prist) Щербаков - 20.10.2020 16:44:05
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Это класс, код приведен выше. Оwner конкретно в данном случае, который сейчас тестирую -  page, а рамках проекта  (owner As MSForms.Control) - любой другой контрол, внутри которого можно отрисовать другой контрол и т.д.

файл с кодами - огромный проект, даже выложив отдельный файл проекта, он отдельно не скомпилируется.
Сейчас попробую выдрать этот кусок кода и выложу  
Изменено: katep - 20.10.2020 16:39:05
 
Цитата
Дмитрий(The_Prist) Щербаков написал:
Плюс Вы уверены, что элемент ListBox, созданный таким образом вообще содержит такие события?
если вместо MSForms.Control владелец форма, то да, все отлично работает. Вопрос возник именно, когда есть вложенность контролов на форме
Цитата
Дмитрий(The_Prist) Щербаков написал:
Как Вы эти события в класс добавляли?
через конструктор
 
Цитата
katep написал:
есть вложенность контролов на форме
у меня на Frame замечательно работает все. Вряд ли в этом проблема.
Попробуйте в модуле класса записать так:
Код
Option Explicit

Public WithEvents ctrl As MSForms.ListBox
 
Private Sub ctrl_Change()
    MsgBox ctrl.Name & " change"
End Sub

Private Sub ctrl_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    MsgBox ctrl.Name & " DblClic"
End Sub
'
Public Sub ctrl_Click()
    MsgBox ctrl.Name & " Click"
End Sub
т.е. убрать отсылку на создание самого контрола, а создавать в обычном модуле(не в модуле формы!):
Код
Sub Test()
    Dim lbEvent As clControlEvents

    Set lbEvent = New clControlEvents
    Set lbEvent.ctrl = UserForm1.Controls("Frame1").Controls.Add("Forms.ListBox.1")
    
    lbEvent.ctrl.AddItem "1"
    lbEvent.ctrl.AddItem "2"
    UserForm1.Show
End Sub
Изменено: Дмитрий(The_Prist) Щербаков - 20.10.2020 17:02:23
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
криво но выложила в отдельный файл. Мне тоже хочется думать, что вложенность ни при чем, хотя с фреймами часто проблемы были

Для примера сделала 2 кнопки, один и тот же класс, в первом случае владелец форма, во втором - page.
В обоих случаях контрол создается внутри класса.

Но уже вижу между ними разницу.
Сейчас попробую ваш вариант, спасибо!
 
Дмитрий, спасибо за помощь.
Решение проблемы найдено.

В том варианте, в который предложили вы по сути точно такая же ситуация, если динамически контролов создается несколько (больше, чем один).

Решение: в модуле формы заведен динамический массив (список динамически создаваемых контролов), куда все они "складываются".  
 
Цитата
katep написал:
если динамически контролов создается несколько
вот это ключевое - там же другой подход должен быть. Нужен массив.  
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
А еще, возможно много раз обсуждалось, у меня вечный конфликт frame и pagе. При наличии хоть одного frame на форме никак не хочет динамически создаваться page. Никакой ошибки, тупо закрывается excel. Может кто знает, как эту беду обойти?
 
Цитата
katep написал:
Никакой ошибки, тупо закрывается excel
вывод прост - отказаться. Потому как это явно проблема где-то "внутри" и решить её нормальными методами вряд ли получится. Page вообще своеобразный элемент.
А зачем Вам вообще все динамически создавать? Неужели нет возможность настроить хотя бы те же Page и Frame заранее?
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
Дмитрий(The_Prist) Щербаков написал:
А зачем Вам вообще все динамически создавать?
конкретно в данном случае архитектура проекта построена не мной, дорабатываем "чужое", приходится подстраиваться под то, что есть.

И откровенно говоря, лучшего решения в рамках vba excel (а это условие заказчика) я бы и не предложила. Попытки уговорить на внешнюю надстройку на .net не увенчались успехом.

Количество pages никогда заранее не известно, может быть 5, 10, 20, как и количество элементов на нем (помимо listbox, который обсуждали выше). И все это в асинхронных потоках грузится по res api из двух разных crm заказчика
Страницы: 1
Наверх