您的位置:首页 > 其它

细品RibbonX(29):dynamicMenu元素详解

2018-03-02 11:20 99 查看
细品RibbonX(29):dynamicMenu元素详解
资料整理来自于论坛
完整版下载地址:http://download.csdn.net/download/nodeman/10264659
 Loading ...
 
dynamicMenu元素的主要目的是在运行时创建菜单,通过VBA回调反馈给控件XML代码。dynamicMenu通过使用getContent回调请求需要创建功能区菜单的XML代码来工作。为ID、图像、回调签名和所有其它属性的XML能够由VBA代码编译,并传递给dynamicMenu。然后执行这段代码,就好像是通常已经使用创建功能区定制编码到XML结构里的菜单一样。
dynamicMenu控件能够创建系统中打开的所有工作簿和工作表的最新列表,提供给网络驱动器里所有文件可更新的菜单层级。
在使用dynamicMenu元素时,必须编写VBA代码。即使您只是想动态创建使用内置控件的菜单,仍然需要编译XML,并通过使用VBA回调反馈到dynamicMenu控件。
1、dynamicMenu元素必需的属性
dynamicMenu元素需要下表1所列的id属性之一。
表1:dynamicMenu元素必需的属性
属性
何时使用
id
当创建自已的动态菜单时
idMso
当使用现有的Microsoft动态菜单时
idQ
当在命名空间之间创建共享的动态菜单时
此外,每个dynamicMenu必须同时具有下表2所示的回调。
表2:dynamicMenu元素必需的回调
静态属性
动态属性
允许值
默认值
VBA回调签名
(none)
getContent
1至1096个字符
(none)
Sub GetContent(control As
 IRibbonControl,
ByRef returnedVal)
2、带有回调签名的可选的静态属性和动态属性
dynamicMenu元素可以使用下表3列出的任一insert属性。
表3:dynamicMenu元素可选的insert属性
INSERT属性允许值默认值何时使用
insertAfterMso
有效的Mso组
在组末尾插入
在Microsoft控件之后插入
insertBeforeMso
有效的Mso组
在组末尾插入
在Microsoft控件之前插入
insertAfterQ
有效的组idQ
在组末尾插入
在共享的命名空间控件之后插入
insertBeforeQ
有效的组idQ
在组末尾插入
在共享的命名空间控件之前插入
也可以为dynamicMenu元素设置下表4所列的任何静态属性或等价的动态属性。
表4:dynamicMenu元素可选的属性和回调
静态属性动态属性允许值默认值动态属性的VBA回调签名
description
getDescription
1至1024个字符
(none)
Sub GetDescription(control
As IRibbonControl,
ByRef returnedVal)
enabled
getEnabled
true,false,1,0
true
Sub GetEnabled(control
As IRibbonControl,
ByRef returnedVal)
image
getImage
1至1024个字符
(none)
Sub GetImage(control
As IRibbonControl,
ByRef returnedVal)
imageMso
getImage
1至1024个字符
(none)
同上
keytip
getKeytip
1至3个字符
(none)
Sub GetKeytip(control
 As IRibbonControl,
ByRef returnedVal)
label
getLabel
1至1024个字符
(none)
Sub GetLabel(control
 As IRibbonControl,
ByRef returnedVal)
screentip
getScreentip
1至1024个字符
(none)
Sub GetScreentip(control
 As IRibbonControl,
ByRef returnedVal)
showImage
getShowImage
true,false,1,0
true
Sub GetShowImage(control
 As IRibbonControl,
ByRef returnedVal)
showLabel
getShowLabel
true,false,1,0
true
Sub GetShowLabel(control
 As IRibbonControl,
ByRef returnedVal)
size
getSize
normal,large
normal
Sub GetSize(control
 As IRibbonControl,
ByRef returnedVal)
supertip
getSupertip
1至1024个字符
(none)
Sub GetSupertip(control
 As IRibbonControl,
ByRef returnedVal)
tag
(none)
1至1024个字符
(none)
(none)
visible
getVisible
true,false,1,0
true
Sub GetVisible(control
 As IRibbonControl,
ByRef returnedVal)
3、dynamicMenu元素允许的子对象
dynamicMenu控件接受下列子对象:
n         button
n         checkbox
n         control
n         dynamicMenu
n         gallery
n         menu
n         menuSeparator
n         splitButton
n         toggleButton
4、dynamicMenu元素的父对象
在下列任何控件内都能放置dymamicMenu控件:
n         box
n         buttonGroup
n         dynamicMenu
n         group
n         menu
n         officeMenu
5、创建自定义控件
前文已提及,创建一个成功的动态菜单的关键是使用VBA代码来为getContent回调提供适合的XML代码。
(1)新建一个工作簿,以.xlsm为扩展名保存后关闭。
(2)在CustomUI Editor中打开该工作簿,并输入下列XML代码:
<customUI
onLoad=“rxIRibbonUI_onLoad“
xmlns=“http://schemas.microsoft.com/office/2006/01/customui“>
   <ribbon
      startFromScratch=“false“>
      <tabs>
         <!– Enter your first tab here –>
         <tab idMso=“TabHome“>
            <group id=“rxgrpNewFile“
              label=“New File“
              insertBeforeMso=“GroupClipboard“>
              <dynamicMenu id=“rxdmnuTemplates“
                label=“Create from…“
                imageMso=“CreateReportFromWizard“
                size=“large“
                getContent=“rxdmnuTemplates_getContent“/>
            </group>
         </tab>
      </tabs>
   </ribbon>
</customUI>
如上所示,用于创建动态菜单的XML代码实际上相当简短。提供了标签和大图像作为菜单的外观,同时需要getContent回调来在运行时创建实际的菜单项。
同时,要为用户提供刷新该菜单的功能,需要使功能区无效,因此需要对customUI元素添加onLoad属性。
(3)生成回调签名,复制代码后关闭CustomUIEditor。
(4)在Excel中打开该工作簿,打开VBE并将回调签名代码粘贴到一个标准模块中。下面编辑回调代码以响应期望的操作。
onLoad回调捕获RibbonUI对象:
Dim rxIRibbonUI AsIRibbonUI
 
SubrxIRibbonUI_onLoad(ribbon As IRibbonUI)
    ‘Callback for onLoad to capture RibbonUI
    Set rxIRibbonUI = ribbon
End Sub
下一步需要为动态菜单创建getContent回调。
SubrxdmnuTemplates_GetContent(control As IRibbonControl, ByRef content)
‘Callback for GetContent toreturn XML used to create dynamicMenu
 
    Dim objFSO As Object
    Dim objTemplateFolder As Object
    Dim file As Object
    Dim sXML As String
    Dim lBtnCount As Long
 
    ‘Create FSO object
    Set objFSO =CreateObject(“Scripting.FileSystemObject”)
 
    ‘Set FSO object to templates folder
    Set objTemplateFolder =objFSO.getfolder(Application.TemplatesPath)
 
    ‘Open the XML string
    sXML = “<menuxmlns=”"http://schemas.microsoft.com/office/2006/01/customui”">”
 
    ‘Add template files
    If objTemplateFolder.Files.Count > 0Then
        For Each file InobjTemplateFolder.Files
            If Not Left(file.Name, 2) = “~$”Then
                Select CaseLCase(Right(file.Name, 4))
                    Case “.xlt”, “xltx”, “xltm”
                        ‘Excel template.
                        sXML = sXML & _
                               “<buttonid=”"rxbtnDyna” & lBtnCount & “”" ” & _
                               “label=”"”& file.Name & “”" ” & _
                              “imageMso=”"FileSaveAsExcel97_2003″” ” & _
                               “tag=”"”& file.Path & “”" ” & _
                              “onAction=”"rxbtnDyna_onAction”"/>” & vbCrLf
                        lBtnCount = lBtnCount +1
                    Case Else
                        ‘Unknown format.  Ignore.
                End Select
            End If
        Next file
    End If
 
    ‘Release the FSO objects
    Set file = Nothing
    Set objTemplateFolder = Nothing
    Set objFSO = Nothing
 
    ‘Check if any items buttons were createdand create a “No Templates” button if not
    If lBtnCount = 0 Then _
       sXML = sXML & “<buttonid=”"rxbtnDyna0″” label=”"No Templates Found”"/>”
 
    ‘Add Refresh button & close the menutags
    sXML = sXML & _
           “<buttonid=”"rxbtnRefresh”" ” & _
           “label=”"Refresh List”" ”& _
          “imageMso=”"RecurrenceEdit”" ” & _
          “onAction=”"rxbtnDyna_onAction”"/>” & _
           “</menu>”
 
    ‘Feed the XML back to the Ribbon
    content = sXML
End Sub
代码看起来很复杂!代码的开头创建FSO对象,设置文件夹对象引用模板文件夹,以便后面的代码查看文件夹中的每个文件。此外,代码中检查以“~$”开始的文件以排除临时文件,使用LCase()函数确保不会遇到区分大小写的问题。
下面主要看看传回给dynamicMenu元素的XML字符串(包含在sXML变量中)。XML字符串包含完整的菜单层次,必须以特定的XML命名空间开始。像customUI元素,每个动态菜单回调必须包括这行以便Ribbon知道如何解释代码并编译。接着是在菜单中添加按钮的XML代码,变量lBtnCount代码添加的按钮数量。
在VBA字符串里使用双引号(”)需要两个双引号。因此,第一个双引号实际上表明接下来的双引号应视为文本。例如,为了得到sXML值id=”rxbtnHello”,需要下面的VBA代码字符串:sXML=”id=””rxbtnHello”””。因此,应注意双引号的规范编写,否则在编写XML和VBA代码时会导致错误。
代码也评估添加到XML字符串中的按钮数。如果lBtnCount变量的值为0,则不需要添加任何按钮,因此创建一个按钮让用户知道没有找到模板。
您还希望用户能够刷新按钮,例如可能创建了一个新模板并想在列表中看到该模板,因此添加相应的XML代码。
从根本上说,dynamicMenu的getContent回调的真实目的是对dynamicMenu对象返回格式良好的XML代码,以便于创建菜单。
此外,还需要创建一个回调处理所创建的按钮:
SubrxbtnDyna_onAction(control As IRibbonControl)
‘Callback for buttononAction
 
    If control.ID = “rxbtnRefresh” Then
        rxIRibbonUI.InvalidateControl(“rxdmnuTemplates”)
    Else
        Workbooks.Add (control.Tag)
    End If
End Sub
该过程检查是否调用Refresh按钮,从而更新列表。如果不是,则基于存储在控件的tag属性中的模板创建新的工作簿。结果如下图所示。

 
没有模板文件!因为模板文件夹中没有模板。此时,创建一个新模板,例如testSample.xlst。然后回到自定义动态菜单的文件,单击“Refresh List”按钮,此时将看到新模板已出现在列表中,如下图所示。
 

 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: