[英]How to find the parent userform of a control in VBA
This code is part of a class module.此代码是 class 模块的一部分。
Private pImg As Image 'For example, pImg = U_Cursor.Img
Public Property Let ItemID(ID As Byte)
pImg.Picture = LoadPicture(ThisWorkbook.Path & "\Images\Img" & ID & ".gif")
*ParentUserform*.Repaint 'ParentUserform is the userform I'm looking for
End Property
I have to force Excel to repaint the userform, otherwise the image sometimes doesn't update on screen.我必须强制 Excel 重新绘制用户窗体,否则图像有时不会在屏幕上更新。
Is there a way to know which userform "pImg" is in?有没有办法知道“pImg”在哪个用户表单中?
If there is no efficient way to do it, I can add another variable to the class module containing the userform name, but I'd prefer not to.如果没有有效的方法,我可以向包含用户窗体名称的 class 模块添加另一个变量,但我不想这样做。
I know this is an old thread, but I wanted to add to the collective wisdom on this "Finding the Parent Userform" topic.我知道这是一个旧线程,但我想补充关于“查找父用户表单”主题的集体智慧。
My Excel VBA project includes object/controls located directly on the Userform as well as obj/ctrls within several Frames.我的 Excel VBA 项目包括直接位于用户窗体上的对象/控件以及几个框架中的对象/控件。 I use the frames to easily adjust the layout of groups of related obj/ctrls instead of coding each of their.Left/.Top individually (ie. code for 1 frame instead of 20 obj/ctrls).我使用框架轻松调整相关 obj/ctrls 组的布局,而不是单独对它们的每个.Left/.Top 进行编码(即,为 1 帧而不是 20 个 obj/ctrls 编码)。
The specific task that I was trying to accomplish was to code a popup menu for the right/click event on several different ListBoxes in order to edit that ListItem's data.我试图完成的具体任务是为几个不同的 ListBox 上的右键/单击事件编写一个弹出菜单,以便编辑该 ListItem 的数据。 The problem that I ran into, was running the Do/Loop up the.Parent tree to find the main Userform, so that I could calc the XY coords to position the menu just below the cursor.我遇到的问题是在 .Parent 树上运行 Do/Loop 以找到主用户窗体,这样我就可以将 XY 坐标计算为 position cursor 正下方的菜单。
After a couple of days... and a reduction of hair (along with their follicles)... I finally figured out that Excel considers the Frame control to be a Userform.几天后......头发(连同毛囊)减少了......我终于弄明白 Excel 认为 Frame 控件是一个用户窗体。 An excerpt from my final loop is as follows...我最后一个循环的摘录如下...
'the callingCtrl obj is declared as Public in a module
'then Set in the MouseUp event for the Listbox
'then in frm_Popup_Menu's Initialize sub ...
Private Sub UserForm_Initialize()
'==============================
' un-related stuff happens here
'==============================
'zero the coordinates - (0,0)
zeroX = 0
zeroY = 0
'adjust zero for the cursor position
zeroX = zeroX + curX
zeroY = zeroY + curY
'adjust zero for the calling control position
zeroX = zeroX + callingCtrl.Left
zeroY = zeroY + callingCtrl.Top
'adjust zero for any intermediate control/object positions
Dim myParent As Object
Set myParent = callingCtrl.Parent
Do Until TypeOf myParent Is MSForms.UserForm And Not LCase(TypeName(myParent)) = "frame"
zeroX = zeroX + myParent.Left
zeroY = zeroY + myParent.Top
'reset to previous parent in the tree
Set myParent = myParent.Parent
Loop
'adjust zero for the form's position
zeroX = zeroX + myParent.Left
zeroY = zeroY + myParent.Top
'adjust zero for borders & margins
zeroX = zeroX + 7
zeroY = zeroY + 25
'set the final coordinates for the cursor position
frm_Popup_Menu.Left = zeroX
frm_Popup_Menu.Top = zeroY
'==============================
' end of related code
'==============================
Hope you find this helpful.希望你觉得这有帮助。 Enjoy.享受。
pImg.Parent
will work if pImg is the direct child of the user form.如果pImg 是用户表单的直接子级,则pImg.Parent
将起作用。 If it is within another container (like a multi or a frame) you'll need to climb the .Parent
tree.如果它在另一个容器中(如多容器或框架),则需要爬上.Parent
树。
With your code in break mode take a look in the Locals window and look at the properties of pImg
在中断模式下查看代码并查看本地窗口并查看pImg
的属性
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.