接 细品RibbonX(29):dynamicMenu元素详解
下一步需要为动态菜单创建getContent回调。 Sub rxdmnuTemplates_GetContent(control As IRibbonControl, ByRef content) ‘Callback for GetContent to return 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 = “<menu xmlns=”"http://schemas.microsoft.com/office/2006/01/customui”">” ‘Add template files If objTemplateFolder.Files.Count > 0 Then For Each file In objTemplateFolder.Files If Not Left(file.Name, 2) = “~$” Then Select Case LCase(Right(file.Name, 4)) Case “.xlt”, “xltx”, “xltm” ‘Excel template. sXML = sXML & _ “<button id=”"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 created and create a “No Templates” button if not If lBtnCount = 0 Then _ sXML = sXML & “<button id=”"rxbtnDyna0″” label=”"No Templates Found”"/>” ‘Add Refresh button & close the menu tags sXML = sXML & _ “<button id=”"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代码,以便于创建菜单。 此外,还需要创建一个回调处理所创建的按钮: Sub rxbtnDyna_onAction(control As IRibbonControl) ‘Callback for button onAction If control.ID = “rxbtnRefresh” Then rxIRibbonUI.InvalidateControl (“rxdmnuTemplates”) Else Workbooks.Add (control.Tag) End If End Sub 该过程检查是否调用Refresh按钮,从而更新列表。如果不是,则基于存储在控件的tag属性中的模板创建新的工作簿。结果如下图所示。
没有模板文件!因为模板文件夹中没有模板。此时,创建一个新模板,例如testSample.xlst。然后回到自定义动态菜单的文件,单击“Refresh List”按钮,此时将看到新模板已出现在列表中,如下图所示。
|