RibbonX:自定义Office 2007功能区——回调(二)
RibbonX:自定义Office 2007功能区
第五章 回调:对自定义UI添加功能的关键-学习笔记
——————————————–
五、组织回调
1、单个的回调处理
当编写XML代码时,可以指定返回回调的多种属性,例如,onAction、getLabel、getVisible、getEnabled,等等。这些属性的每一个都必须处理。下面的示例演示通过组中产生3个按钮的过程,虽然该示例以Word文档为例,但也可以在Excel中使用。
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon>
<tabs>
<tab id=”rxtabDemo”
label=”My Custom Tab”
insertBeforeMso=”TabHome”>
<group id=”rxgrpDemo”
label=”My Demo Group”>
<button id=”rxbtnPaste”
label=”My Paste Button”
size=”normal”
onAction=”rxbtnPaste_click”
imageMso=”Paste”
tag=”Custom Paste Button”/>
<button id=”rxbtnCopy”
label=”My Copy Button”
size=”normal”
onAction=”rxbtnCopy_click”
imageMso=”Copy”
tag=”Custom Copy Button”/>
<button id=”rxbtnCut”
label=”My Cut Button”
size=”normal”
onAction=”rxbtnCut_click”
imageMso=”Cut”
tag=”Custom Cut Button”/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
每个按钮都有其onAction属性,因此如果企图对按钮添加功能,则必须处理每个属性:
‘Callback for rxbtnPaste onAction
Sub rxbtnPaste_click(control As IRibbonControl)
MsgBox “您单击了” & control.Tag, vbInformation
End Sub
‘Callback for rxbtnCopy onAction
Sub rxbtnCopy_click(control As IRibbonControl)
MsgBox “您单击了” & control.Tag, vbInformation
End Sub
‘Callback for rxbtnCut onAction
Sub rxbtnCut_click(control As IRibbonControl)
MsgBox “您单击了” & control.Tag, vbInformation
End Sub
一种可供选择的方法是一次处理多个属性。
2、使用全局回调处理
(1)全局回调处理能用于一次处理几个控件。如果以标准化方式命名全局处理,那么效果将更好,因为可以立即从单个控件中区分全局控件。
(2)使用全局回调的原因是因为某些指令可能重复,甚至当指令不重复时,对某种控件为某项操作共享相同的属性仍有好处,如onAction属性。此外,如果操作相同,那么过程能组合在单个的回调处理中。
(3)能利用这种优势减少要处理的回调数。
(4)例如,下列对象:tab,group,button,都共享一个通用的属性getLabel。如前所述,当需要对每个控件动态应用值时,不需要在XML代码中为每个控件编写getLabel回调。相反,可以在VBA过程中在单个过程内将共享任务放在一起,而且因为是回调,不需要遍历XML中指定的控件,将自动遍历控件直至所有控件有所需的值。
(5)仍以上节中的示例,在前面的XML代码中修改每个按钮的onAction属性如下:
onAction=”rxshared_click”
将产生单个的回调,用于处理具有onAction属性和共享标签的任何控件。
接着,在VBA中为每个按钮处理该回调,使用下面的一小段代码:
Sub rxshared_click(control As IRibbonControl)
MsgBox “您单击了” & control.Tag, vbInformation
End Sub
也能使用Select Case语句分开每个按钮并赋予其特定的代码:
Sub rxshared_click(control As IRibbonControl)
Select Case control.ID
Case “rxbtnPaste”
‘为rxbtnPaste按钮的代码
Case “rxbtnCopy”
‘为rxbtnCopy按钮的代码
Case “rxbtnCut”
‘为rxbtnCut按钮的代码
End Select
End Sub
3、在Access中处理回调
在创建定制时,Access在许多方面都是独特的。
在Access中,能够使用VBA或宏处理回调。当使用Word和Excel时,宏通常指VBA指令,而Access中,宏是创建的对象。此外,因为宏有预定义指令,通常仅需一个参数。
(1)使用VBA处理回调
首先,需要引用Office 12 Object Library,否则会出现错误消息。
例如,下面的XML代码为Access中自定义选项卡/组创建一个按钮:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon>
<tabs>
<tab id=”rxtabDemo”
label=”My Custom Tab”
insertBeforeMso=”TabHomeAccess”>
<group id=”rxgrpDemo”
label=”My Demo Group”>
<button id=”rxbtnReport”
label=”My Report Button”
size=”large”
onAction=”rxbtnReport_click”
imageMso=”CreateReport”
tag=”Create Report”/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
在工程中添加一个标准模块,并输入下面的代码:
Sub rxbtnReport_click(control As IRibbonControl)
On Error GoTo Err_Handler
DoCmd.OpenReport “MyReport”, acViewDesign
Exit Sub
Err_Handler:
MsgBox Err.Description, vbCritical, “Err Number:” & Err.Number
End Sub
本例中,单击按钮后将在视图预览模式下打开名为MyReport的报表。
(2)使用宏处理回调
在Access 12中,macro对象是处理回调的另一种方式。
假设希望使用宏处理onAction属性,需要指定onAction属性:
onAction=”rxMacroName.objectName”
其中,rxMacroName指定在Access中创建的宏对象的名称(宏对象自身)。
objectName指在XML代码中创建的对象id(宏对象是宏名称)。
下图将有助于理解:
现在首先创建新的选项卡和组并在其中添加按钮:
<button id=”rxbtnPaste”
label=”My Paste Button”
size=”normal”
onAction=”rxsharedMacro.rxbtnPaste”
imageMso=”Paste”
tag=”Custom Paste Button”/>
<button id=”rxbtnCopy”
label=”My Copy Button”
size=”normal”
onAction=”rxsharedMacro.rxbtnCopy”
imageMso=”Copy”
tag=”Custom Copy Button”/>
<button id=”rxbtnCut”
label=”My Cut Button”
size=”normal”
onAction=”rxsharedMacro.rxbtnCut”
imageMso=”Cut”
tag=”Custom Cut Button”/>
然后,在Access中添加新的宏对象并将其命名为rxsharedMacro。在设计视图中打开宏,并添加三个新的宏指令。每个使用在XML代码中onAction属性的点之后的文本命名。添加宏指令:一个Beep和2个消息框。
单击自定义选项卡中的按钮,出现类似下面的消息框:
六、使UI组件无效
Ribbon的一个重要方面是使Ribbon无效或指定的控件无效。
某些操作仅当使整个Ribbon无效才能执行,而另一些操作只需通过使指定控件无效来完成。
1、无效能处理什么?为什么需要?
IRibbonUI对象包含两个方法:Invalidate和InvalidateControl。
表:IRibbonUI对象模型
方法 用途
Invalidate() 为更新而标记整个功能区(顺序标记其中的每个控件)
InvalidateControl(strControlID) 为更新而标记特定的控件(被更新的控件作为字符串传递到方法的参数中)(strControlID)
理解Invalidate方法的关键是该方法使UI中每个控件都无效,意味着强制调用在UI中定义的所有回调。此外,也将导致更新所有控件,而无论其是否有回调。当使Ribbon无效时,在Ribbon中作出调用,在UI中指定的每个过程都将运行。
“刷新”指在打开工程时简单地更新在UI中已经装载的控件;“重新装载”指卸载并重新装载UI中的整个项目。
除非确实需要作用整个Ribbon,更好的选择是在执行期间的指定时刻使单个控件无效,即当需要时仅使该控件无效。
要使整个Ribbon或Ribbon中指定的控件无效,需要设置代表IRibbonUI对象的全局变量,可通过在onLoad属性中指定回调来实现:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui” onLoad=”rxIRibbonUI_onLoad”>
</customUI>
接下来,编写VBA代码处理在onLoad属性中指定的回调:
Public grxIRibbonUI As IRibbonUI
Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
Set grxIRibbonUI=ribbon
End Sub
注意,代表IRibbonUI对象的变量在标准模块的全局声明区中声明,以便于能被工程的其他部分访问。
2、使整个Ribbon无效
(1)创建一个新的Excel文件,并以启用宏的工作簿保存。
(2)使用CustomUI Editor,在工作簿文件中添加XML代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui” onLoad=”rxIRibbonUI_onLoad”>
<ribbon>
<tabs>
<tab id=”rxtabDemo”
label=”My Custom Tab”
insertBeforeMso=”TabHome”>
<group id=”rxgrpDemo”
label=”My Demo Group”>
<button id=”rxbtn”
getLabel=”rxshared_getLabel”
size=”normal”
onAction=”rxshared_click”
imageMso=”FillRight”/>
<button id=”rxbtn2″
getLabel=”rxshared_getLabel”
size=”normal”
onAction=”rxshared_click”
imageMso=”FillRight”/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
(3)保存并验证代码。
(4)单击“Generate Callbacks”按钮生成回调。
(5)复制回调代码并关闭该文件。
(6)在Excel中打开该工作簿,添加一个标准模块。
(7)粘贴代码到该模块中,并补充代码。
Public grxIRibbonUI As IRibbonUI
Public glngCount1 As Long
Public glngCount2 As Long
‘Callback for customUI.onLoad
Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
Set grxIRibbonUI = ribbon
End Sub
‘Callback for rxbtn onAction
Sub rxshared_click(control As IRibbonControl)
grxIRibbonUI.Invalidate
End Sub
‘Callback for rxbtn getLabel
Sub rxshared_getLabel(control As IRibbonControl, ByRef returnedVal)
Select Case control.ID
Case “rxbtn”
returnedVal = “功能区无效:” & glngCount1 & “次.”
glngCount1 = glngCount1 + 1
Case “rxbtn2″
returnedVal = “功能区无效:” & glngCount2 & “次.”
glngCount2 = glngCount2 + 1
End Select
End Sub
注意,此时单击任一按钮,两个标签均更新,如下图。因为单击按钮时代码使整个Ribbon无效,所以两个控件都无效,共享的getLabel过程为第一个按钮调用一次,又为第二个按钮所调用。
3、使单个控件无效
仍以上面的例子,仅使触发click事件的按钮无效。将共享的click事件和共享的getLabel事件修改如下:
Public grxIRibbonUI As IRibbonUI
Public glngCount1 As Long
Public glngCount2 As Long
‘Callback for customUI.onLoad
Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
Set grxIRibbonUI = ribbon
End Sub
‘Callback for rxbtn onAction
Sub rxshared_click(control As IRibbonControl)
Select Case control.ID
Case “rxbtn”
glngCount1 = glngCount1 + 1
Case “rxbtn2″
glngCount2 = glngCount2 + 1
End Select
grxIRibbonUI.InvalidateControl (control.ID)
End Sub
‘Callback for rxbtn getLabel
Sub rxshared_getLabel(control As IRibbonControl, ByRef returnedVal)
Select Case control.ID
Case “rxbtn”
returnedVal = “功能区无效:” & glngCount1 & “次.”
Case “rxbtn2″
returnedVal = “功能区无效:” & glngCount2 & “次.”
End Select
End Sub
此时,只会使单击的控件无效,如下图。

发表评论