Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 在userform中的动态对象上检测鼠标按下事件_Excel_Vba_Userform_Mousedown - Fatal编程技术网

Excel 在userform中的动态对象上检测鼠标按下事件

Excel 在userform中的动态对象上检测鼠标按下事件,excel,vba,userform,mousedown,Excel,Vba,Userform,Mousedown,我在Userform的一个框架内有一个动态的选项按钮范围。选项按钮的数量根据表中的列数而变化。每个按钮都根据列标签进行标记。当一个人选择一个选项时,我需要一个列表框来填充该表列中的项目。 填充选项按钮和列表框非常简单。我知道如何检测已知Userformobjects上的鼠标按下事件。但这些按钮只是通过编码存在的,并且会有所不同。如何在实际不存在的对象上检测鼠标下降? 我已经尝试过为框架创建MouseDown类的代码您需要将控件包装在类模块中,例如,DynamicActionButton: Opt

我在Userform的一个框架内有一个动态的选项按钮范围。选项按钮的数量根据表中的列数而变化。每个按钮都根据列标签进行标记。当一个人选择一个选项时,我需要一个列表框来填充该表列中的项目。 填充选项按钮和列表框非常简单。我知道如何检测已知Userformobjects上的鼠标按下事件。但这些按钮只是通过编码存在的,并且会有所不同。如何在实际不存在的对象上检测鼠标下降?
我已经尝试过为框架创建MouseDown类的代码

您需要将控件包装在类模块中,例如,
DynamicActionButton

Option Explicit
Private WithEvents ControlEvents As MSForms.OptionButton

Public Sub Initialize(ByVal ctrl As MSForms.OptionButton)
    If Not ControlEvents Is Nothing Then ThrowAlreadyInitialized
    Set ControlEvents = ctrl
End Property

Private Property Get AsControl() As MSForms.Control
    Set AsControl = ControlEvents
End Property

Private Sub ThrowAlreadyInitialized()
    Err.Raise 5, TypeName(Me), "Invalid Operation: This control is already initialized."
End Sub

Private Sub ControlEvents_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim parentForm As UserForm1 'todo: use your actual UserForm subtype
    Set parentForm = AsControl.Parent 
    'handle mousedown here.
End Sub
创建动态控件时,您需要一个模块级的
集合
来保存
动态按钮
实例-否则,当到达
结束子对象
时,它们将超出范围,并且您将永远无法处理它们的任何事件

Private DynamicControls As Collection

Private Sub Class_Initialize()
    Set DynamicControls = New Collection
    'todo invoke CreateOptionButton
End Sub

Private Sub CreateOptionButton() 'todo parameterize
    Dim ctrl As MSForms.OptionButton
    Set ctrl = Me.Controls.Add(...)

    Dim wrapper As DynamicOptionButton
    Set wrapper = New DynamicOptionButton
    wrapper.Initialize ctrl

    DynamicControls.Add wrapper
End Sub

创建一个类来处理运行时创建的对象上的事件是正确的方法,但是您说您已经尝试过了。告诉我们代码我清楚地记得不久前写过一个关于处理动态控件事件的答案,但我找不到:(我使用了此线程中的代码。您的代码描述中缺少的是ControlEvents的标签用于标识对象,如ControlEvents.Caption和ControlEvents.Value。在解决此问题之前,虽然代码正常工作,但它没有告诉我选择了哪个选项按钮。但现在一切都很好工作非常出色。多亏了一束,您还可以将其转换为
MSForms.Control
,并使用
Tag
属性像ID一样保存元数据-这样,逻辑就不依赖于标题,而在其他情况下可能需要本地化:避免使用像元数据(例如,唯一ID)这样的仅限于UI的内容(如标题)有助于分离关注点,并使事情整体上更加稳健。干杯!