香港豆瓣高分电视剧:细品RibbonX(49):在功能区中使用上下文控件

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 12:35:10
上下文选项卡对新UI的功能提供了极大的推进作用。当用户对某对象执行特定的任务时就会出现特定的选项卡。例如,在Excel中处理图表时,一个上下文选项卡提供用于图表处理的额外选项。本文将介绍创建和执行这些特定的选项卡,以及如何修改内置的上下文选项卡,也介绍如何定制或替换内置的弹出菜单,如何创建自已的上下文弹出菜单。最后,探讨创建一个使用多种语言的UI。
使项目上下文
使项目上下文意味着必须响应所做的内容,例如操控表或图片。根据对上下文控件的定义,需要在新Office UI中使用上下文选项卡集合来执行任务。然而,也不总是这样。
下面介绍上下文控件的概念,例如选项卡、组和通用控件。
选项卡
当执行上下文敏感的命令时,立即想到的是上下文选项卡。作为使Ribbon的功能完整的一部分,这些特定的选项卡将根据所选择的对象或这些对象是否获得焦点而从功能区中出现和消失,例如图表、数据透视表或图片。
下图显示了名为“图片工具”的tabSet,包含一个名为“格式”的选项卡。

要实现这样的解决方案,需要使用上下文选项卡集合和tabSet元素。下面的XML标记作为上下文选项卡集和相应的选项卡的容器:

contextualTabs集合是每个tabSet的父对象,同样选项卡的collection对象是选项卡的父对象。可以使用上述代码来创建自已的上下文敏感功能,访问内置的tabSets来修改它们。不巧的是,这样的tabSets扩展不能应用到Excel或Word,仅能对Access的窗体和报表提供这样的扩展。当在Access中使用自定义选项卡tabSets时,需要按下列方式引用扩展的tabSet:

在这个tabSet里,创建上下文选项卡UI。
对于Excel和Word,需要通过完全控制内置的上下文选项卡或者通过联合getVisible属性使用事件来使选项卡的行为像上下文选项卡。

例如,当用户处理Excel工作簿中的工作表Sheet1时,希望仅使字体组和插入图表组可见。XML代码:

使用在XML中定义的共享回调,现在能够通过使用想控制的特定工作表的自定义属性来决定属性的返回值。使用下面的代码:

Sub rxShared_getVisible(control As IRibbonControl, ByRef returnedVal)Select Case control.IDCase "GroupFont"returnedVal = Sheet1.rxGroupFontVisibleCase "GroupInsertChartsExcel"returnedVal = Sheet1.rxGroupInsertChartsExcelEnd SelectEnd Sub

根据自定义的属性值设置该属性的值。首先,设置Ribbon对象,这样当文档打开时以便设置该Ribbon为ThisWorkbook对象的属性。下面的代码放置在ThisWorkbook模块中:

Private pRibbonUI As IRibbonUI Public Property Let rxIRibbonUI(iRib As IRibbonUI)Set pRibbonUI = iRibEnd Property Public Property Get rxIRibbonUI() As IRibbonUISet rxIRibbonUI = pRibbonUIEnd Property

其次,指定想控制的工作表的自定义属性,代码如下所示。自定义属性可读写,以便执行期间的任何时候都能重新赋值。

Private pblnGroupFontVisible As BooleanPrivate pblnGroupChartVisible As Boolean Property Let rxGroupFontVisible(ByVal blnVisible As Boolean)pblnGroupFontVisible = blnVisibleEnd Property Property Get rxGroupFontVisible() As BooleanrxGroupFontVisible = pblnGroupFontVisibleEnd Property Property Let rxGroupInsertChartsExcel(ByVal blnVisible As Boolean)pblnGroupChartVisible = blnVisibleEnd Property Property Get rxGroupInsertChartsExcel() As BooleanrxGroupInsertChartsExcel = pblnGroupChartVisibleEnd Property

最后,根据需要修改自定义属性。这里,我们希望当指定工作表是活动工作表时显示这些组,因此使用Worksheet_Activate和Worksheet_Deactivate事件来修改属性值,代码如下:

Private Sub Worksheet_Activate()Sheet1.rxGroupFontVisible = TrueSheet1.rxGroupInsertChartsExcel = TrueThisWorkbook.rxIRibbonUI.InvalidateEnd Sub Private Sub Worksheet_Deactivate()Sheet1.rxGroupFontVisible = FalseSheet1.rxGroupInsertChartsExcel = FalseThisWorkbook.rxIRibbonUI.InvalidateEnd Sub

当激活/取消激活该工作表时,显示或隐藏相应的组。
使用不明显的方法
使用可见性创建上下文敏感的选项卡和组可能有点不正规,但是确实是达到目标的有效的方式。然而,这种方式不是在所有情形下都可用,特别是在处理内置组中的内置控件时。
启用和禁用控件
可以使用enabled属性决定控件是否启用。
下面通过使用getEnabled属性提供上下文敏感的控件。要禁用命令,必须引用该命令本身和按钮或通用控件,例如禁用复制和剪切命令的XML代码如下:

下一步,添加共享回调来处理要执行的程序:

Sub rxShared_getEnabled(control As IRibbonControl, ByRef returnedVal)Select Case control.IDCase "Copy"returnedVal = Sheet1.rxCopyEnabledCase "Cut"returnedVal = Sheet1.rxCutEnabledEnd SelectEnd Sub

同样,使用自定义属性指定回调的返回值。
修改内置的选项卡集
下图展示了对内置的图表工具上下文选项卡集中添加的自定义选项卡。

正确修改内置选项卡集的关键是知道想要定制的tabSet的idMso,本例中,我们想修改TabSetChartTools选项卡集。
因此,在内置选项卡集中添加自定义选项卡的XML代码如下:

然而,有时我们想移除上下文图表选项卡中的所有的内置选项卡,仅在该选项卡集中添加一些非常特别的编辑工具。
首先,我们看看图表工具选项卡集中的选项卡,如下表所示。
表:图表工具选项卡集中默认的选项卡

选项卡名 描述 TabChartToolsDesign 提供用户设计所选择的图表的工具,例如内置样式选项、数据选择、图表类型,等等。 TabChartToolsLayout 指供用户布局所选择的图表的工具,例如标签、趋势线,等等。 TabChartToolsFormat 提供用户格式化所选择的图表的工具,例如形状样式、文本填充、文本效果、排列,等等。


选项卡不会像按钮一样提供enabled属性,因而使用其visible属性控制其出现。通过使选项卡不可见,其中的所有对象都将从UI中消失,但不会禁用其中包含的控件。
接着完成上面的示例,其XML代码如下:

  

修改后的图表工具选项卡如下图所示。仅当选择图表时才出现。

处理上下文弹出菜单
当在某对象上右击或者在有弹出菜单的工作环境中右击时,会出现弹出菜单。与上下文选项卡相似,弹出菜单显示与活动对象相关的选项。
弹出菜单的设置基于VBA,不需要XML代码,它们仍然基于命令栏对象。大多数弹出菜单都能够被定制,然而基于新的OfficeArt不能够被定制。下图显示了Excel中内置弹出菜单的示例。

上图显示的弹出菜单称为“Cell”,索引值等于36。
不能够定制“Mini工具栏”,然而可以在应用程序选项中控制其是否显现。
完全取代内置的弹出菜单
当在Excel工作表单元格中右击时,将得到单元格弹出菜单,如上图所示。然而,可能有一个区域需要合适的自定义弹出菜单,如下图所示。

在编写代码前,让我们先看看该自定义的弹出菜单需要做什么:

  • 必须在单元格弹出菜单的位置显示。
  • 必须仅显示在预先确定的区域。本例中为单元格区域A1:O32。

首先,添加下面的代码到想要取代内置单元格弹出菜单的工作表代码模块中:

Private Sub Worksheet_BeforeRightClick(ByVal Target As Excel.Range, _Cancel As Boolean)If Union(Target.Range("A1"), Range("A1:O32")).Address = _Range("A1:O32").Address ThenCommandBars(MYPOPUP).ShowPopupCancel = TrueEnd IfEnd Sub

下一步,需要在工作簿代码窗口添加两个过程。一个过程指工作簿的Open事件,用来创建弹出菜单;另一个过程指工作簿的Close事件,用来删除弹出菜单。

Private Sub Workbook_Open()Call mnuPopupEnd Sub Private Sub Workbook_BeforeClose(Cancel As Boolean)Call delPopupEnd Sub

然后,在标准模块中包含产生弹出菜单以及删除该菜单的代码,即编写mnuPopup过程和delPopup过程,通过声明公共常量MYPOPUP开始,以便在工程中的其它过程中可用:

Public Const MYPOPUP As String = "MY POPUP" Sub mnuPopup()Dim cmdBar As CommandBarDim mnu As CommandBarButton delPopup Set cmdBar = CommandBars.Add _(Name:=MYPOPUP, Position:=msoBarPopup, Temporary:=True) Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)With mnu.Caption = "Bold".OnAction = "bold".FaceId = 113End With Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)With mnu.Caption = "Italics".OnAction = "italics".FaceId = 114End With Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)With mnu.Caption = "Underline".OnAction = "underline".FaceId = 115End With Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)With mnu.Caption = "&About...".OnAction = "about".FaceId = 326.BeginGroup = TrueEnd With Set mnu = cmdBar.Controls.Add(Type:=msoControlButton)With mnu.Caption = "&Help".OnAction = "help".FaceId = 984.BeginGroup = TrueEnd With End Sub Sub delPopup()On Error Resume NextCommandBars(MYPOPUP).DeleteEnd Sub

当打开工作簿时,执行第一个过程;当关闭工作簿时,执行第二个过程。
最后,添加弹出菜单中按钮的功能,代码如下:

Sub bold()Selection.Font.bold = Not Selection.Font.boldEnd Sub Sub italics()Selection.Font.Italic = Not Selection.Font.ItalicEnd Sub Sub underline()If Selection.Font.underline = xlUnderlineStyleSingle ThenSelection.Font.underline = xlUnderlineStyleNoneElseSelection.Font.underline = xlUnderlineStyleSingleEnd IfEnd Sub

在弹出菜单中添加单独的项目
自定义内置弹出菜单的另一种有用的方式是添加新功能。如下图所示,我们在工作表标签右击后出现的弹出菜单中添加新的功能,只需单击该功能应能按字母顺序对工作表排序。

在标准模块中输入下面的代码:

Sub addButton()Dim cmdbar As CommandBarDim btn As CommandBarButton resetPopupOn Error GoTo Err_HandlerSet cmdbar = Application.CommandBars("Ply") Set btn = cmdbar.Controls.Add(Type:=msoControlButton, Before:=1) With btn.Style = msoButtonIconAndCaption.Caption = "Order sheet tabs".FaceId = 210.OnAction = "orderTabs"End WithExit SubErr_Handler:MsgBox Err.Description, vbCritical, Err.NumberEnd Sub

与上例一样,如果想在打开工作簿时自动实现该功能,则在工作簿的打开事件中添加调用该过程,此外,在工作簿的关闭事件中添加调用恢复原菜单的功能。恢复菜单的代码如下:

Sub resetPopup()Application.CommandBars("Ply").ResetEnd Sub

下面,编写代码实现当单击添加的按钮时所实现的功能:

Sub orderTabs()Dim i As LongDim j As LongDim n As Long n = ActiveWorkbook.Sheets.Count If n = 1 ThenMsgBox "这个工作簿中仅有一个工作表!", _vbInformationExit SubEnd If For i = 1 To n - 1For j = i + 1 To nIf Sheets(j).Name < Sheets(i).Name ThenSheets(j).Move Before:=Sheets(i)End IfNextNextEnd Sub

使用多种语言的UI
本例的目的是让用户能够选择他们喜欢的语言。示例中将提供两种语言,下图显示了我们将在Excel中创建的示例。

实现上述目的需要完成四项任务:

  • 每个控件的标签必须在运行时修改,因此使用getLabel属性。
  • 因为这是在所有控件中共享的属性,所以我们使用一个共享的回调来处理变化。这也避免了许多代码量。
  • 使用工作表保持控件的名字和翻译。可以隐藏该工作表,以便用户不容易访问它。
  • 使用VLookup函数搜索列表中的控件,返回标签值。

控件名和翻译是实现该解决方案的关键元素,一个工作表示例如下图所示。

可以为包含翻译的区域定义动态区域,也可以将区域转换为表,但是在里只是提供一个示例,所以使用固定区域。下面开始编写VBA代码。
首先,定义一些需要使用的变量。在标准模块声明部分声明下列全局变量:

Public grxIRibbonUI As IRibbonUIPublic giColControls As IntegerPublic gWS As Worksheet

第一个变量是Ribbon对象,第二个变量指向语言版本所在的列;第三个变量指向包含翻译的工作表对象。
接着,使用onLoad事件设置这些变量以便后面使用:

Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)Set grxIRibbonUI = ribbongiColControls = 2Set gWS = ThisWorkbook.Sheets("Languages")Application.SendKeys "%UN{RETURN}"End Sub

这段代码执行下列任务:

  • 设置ribbon对象
  • 决定翻译位于的初始列
  • 设置包含翻译的工作表
  • 向应用程序发送快捷键Alt+UN,以便当打开该工作簿时选择自定义选项卡

当打开文档时将装载初始标签,因此需要处理共享的getLabel回调,代码如下:

Sub rxshared_getLabel(control As IRibbonControl, ByRef returnedVal)On Error Resume NextreturnedVal = Application.WorksheetFunction.VLookup( _control.ID, gWS.Range("A1:C200"), giColControls, 0)End Sub

当用户从UI的splitButton/menu中选择不同语言时调用代码。当用户单击所选择的语言命令时,需要使功能区无效以便重新装载值到UI中,代码如下:

Sub rxbtnshared_Click(control As IRibbonControl)Select Case control.IDCase "rxbtnSpanish"giColControls = 3Case "rxbtnEnglish"giColControls = 2End SelectgrxIRibbonUI.InvalidateEnd Sub

使用Select语句选择两种可用的语言。如果选择的是Spanish,查找的列被设置为3;如果选择English,该列被设置为2(缺省值)。