WPF 功能区控件图形生成器






4.58/5 (19投票s)
一篇介绍 Ribbon Builder 的文章,这是一个用于创建功能区控件的工具。
支持 RibbonControl
库 版本 1.0.0.9
引言
此工具是现有 Code Project 页面 WPF C# 功能区控件库 的补充,它不提供功能区控件,而是利用该项目的其他功能区控件库,通过用户界面 (UI) 生成特定的布局。该软件提供了一种快速生成完整功能区控件的方法,无需编写代码;但请注意,它不生成事件处理程序钩子,因为这超出了应用程序的范围,应用程序仅用于生成布局。生成的代码适用于旧式的手动连接方法,该方法已不再推荐;它将在下一个版本中更新。
请注意,由于功能区控件库仍处于 alpha 阶段,并且编辑器(即本文的软件)与库之间存在紧密的关联,因此该编辑器与库未来版本的兼容性尚不明确。我将努力在适当的时候更新此应用程序。该编辑器不,而且将来也不会支持第三方组件。此应用程序是第一个版本,因此可能包含错误,导致其与库不兼容,请报告这些错误!此外,一些非核心功能尚未实现(例如,移除子项、上移、下移、保存、加载),但可以创建所有支持的功能区布局并使用生成的代码;缺失的功能将在后续版本中添加。
背景
“功能区是一个图形用户界面小部件,由窗口顶部的一条带组成,该带显示了程序可以执行的所有功能,并根据数据的上下文出现其他功能区。
使用功能区的主要驱动理念之一是增强可用性;通过将程序的功能和命令集中在一个易于识别的地方,用户无需浏览多个级别的分层菜单、工具栏或任务窗格即可找到正确的命令。
最近,功能区已在 Microsoft Office 2007 中实现,Microsoft 将其称为 Office Fluent 功能区,并取代了菜单、工具栏和许多任务窗格。Microsoft 声称这将把所有相关功能集中在一个地方,从而提高可用性。
功能区是一个窗格,包含控件(如按钮和图标),这些控件被组织成一组选项卡,每个选项卡包含一组相关的命令。每个应用程序都有不同的选项卡集,用于公开该应用程序提供的功能。
例如,Excel 有一个用于处理公式的选项卡,Word 有一个用于创建信封和邮件的选项卡。在每个选项卡内,相关的命令被分组在一起。功能区的目的是使应用程序的功能更易于发现和访问,并且比 Office 2007 之前的版本中使用的基于菜单的 UI 所需的鼠标点击次数更少。
有些选项卡称为上下文选项卡,仅在选择对象时出现。上下文选项卡公开仅特定于当前对象的函数。例如,选择图片会弹出图片工具上下文选项卡,其中包含处理图片的命令。同样,聚焦于表格会在特定选项卡中公开与表格相关的选项。当对象未被选中时,上下文选项卡保持隐藏。” --- 维基百科 功能区 (计算)。
WPF C# 功能区控件库文章介绍了一个用于生成 Microsoft Office 2007 风格功能区界面的库;虽然包含的源代码和二进制文件处于 ALPHA 发布阶段,但应该可以实现最复杂的功能区风格的界面(尽管需要进行少量修改)。目前该库不支持通过 WPF XAML 代码创建功能区控件,但需要通过 C# 后台代码创建功能区栏。本文和软件通过图形化方法生成布局,在一定程度上解决了这种对后台代码创建的依赖。
使用应用程序
启动 RibbonDesigner.exe
后,您将看到主应用程序界面,布局如下。请注意,您不会看到功能区栏,因为它还没有添加任何控件,但基础 RibbonController
已初始化并链接到应用程序。
Ribbon
功能区显示正在创建的功能区栏的视图;它是完全功能的,因为最终用于生成实际应用程序的代码实际上被用于实现预览。设计结构的更新会自动应用于预览。但请注意,带有下拉菜单的项目将不会显示其菜单,因为设计器不创建 ContextMenu
;这不是一个 bug,而且 ContextMenu
的生成超出了应用程序规范的范围。RibbonPreviewBoxes
的弹出窗口可以正常工作。此外,当 RibbonGroupBox
最小化到其最小形式时,生成的下拉按钮也将正常工作。
堆栈 (内容堆栈)
堆栈允许创建子节点,从而创建功能区的结构;功能区组件的子项嵌套在表示组件的节点树结构中。节点可以最小化和展开以允许更简单的构建和聚焦,但添加了子项的节点在新子项添加时(如果尚未展开)会自动重新展开。
添加子项按钮会将合适的子项添加到当前选定的元素;在许多情况下,一个控件只能添加一种类型的控件,但如果情况并非如此,则会显示一个包含有效子项类型的选择对话框(如下所示)。多次单击添加子项按钮会添加多个子项;任何支持添加子项的节点都可以接受任意数量的子项,即没有控件只允许一个子项。
移除子项目前未实现。由于底层库类的即将更改,上移和下移按钮也未实现。
元素选项
元素选项显示堆栈中当前选定元素的相应选项(如上)。通常有几个选项;
- 名称,也称为 .Text,放在组件上的某个字符串名称
- 变量名,代码中对象的变量名
- 设置图像按钮,也称为 .Image,放在组件上的图像;强烈建议使用便携式网络图形 (PNG)。
应用程序选项
样式下拉按钮允许选择 RibbonStyleHandler
中定义的标准功能区颜色。
生成代码按钮将打开一个新窗口,其中包含重现预览功能区所需的源代码。请注意,在您自己的应用程序中使用代码时,您必须按照 WPF C# 功能区控件库 一文的说明链接 RibbonController
。强烈建议在使用代码时使用设计器提供的动态链接库 (dll)(即 RibbonControl.dll
以确保代码兼容性,但对代码的修改通常并不复杂,因此尝试修复更新库时的任何编译错误是值得的。非常感谢能为生成的源代码对话框提供语法高亮的人。为上述屏幕截图生成的代码如下;
RibbonController controller = new RibbonController(ribbonHook,
titleHook,
parentWindow);
RibbonBar homeRibbonBar = new RibbonBar();
homeRibbonBar.Text = Home;
RibbonBar insertRibbonBar = new RibbonBar();
insertRibbonBar.Text = Insert;
RibbonBar reviewRibbonBar = new RibbonBar();
reviewRibbonBar.Text = Review;
RibbonGroupBox clipboardGroupBox = new RibbonGroupBox();
clipboardGroupBox.Text = Clipboard;
clipboardGroupBox.ShowLabelButton = false;
RibbonGroupBox controlsGroupBox = new RibbonGroupBox();
controlsGroupBox.Text = Controls;
controlsGroupBox.ShowLabelButton = false;
RibbonDoubleButton pasteButton = new RibbonDoubleButton();
pasteButton.Text = Paste;
pasteButton.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
RibbonThreeRowsLayout ribbon3RowsLayout_1 = new RibbonThreeRowsLayout();
RibbonThirdLabel ribbonThirdLabel_1 = new RibbonThirdLabel();
ribbonThirdLabel_1.Text = Cut;
ribbonThirdLabel_1.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/cut.png", UriKind.RelativeOrAbsolute));
RibbonThirdLabel ribbonThirdLabel_2 = new RibbonThirdLabel();
ribbonThirdLabel_2.Text = Copy;
ribbonThirdLabel_2.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/copy.png", UriKind.RelativeOrAbsolute));
ribbonThirdLabel_2.SubMenu = new ContextMenu();
RibbonThirdLabel ribbonThirdLabel_3 = new RibbonThirdLabel();
ribbonThirdLabel_3.Text = Format Painter;
ribbonThirdLabel_3.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/preview.png", UriKind.RelativeOrAbsolute));
RibbonTwoRowsLayout ribbon2RowsLayout_1 = new RibbonTwoRowsLayout();
RibbonHalfButtonGroup ribbonHalfButtonGroup_1 = new RibbonHalfButtonGroup();
RibbonHalfButtonGroup ribbonHalfButtonGroup_2 = new RibbonHalfButtonGroup();
RibbonHalfButton ribbonHalfButton_1 = new RibbonHalfButton();
ribbonHalfButton_1.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/e-mail.png", UriKind.RelativeOrAbsolute));
RibbonHalfButton ribbonHalfButton_2 = new RibbonHalfButton();
ribbonHalfButton_2.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/go_to_program_s_website.png", UriKind.RelativeOrAbsolute));
RibbonHalfButton ribbonHalfButton_3 = new RibbonHalfButton();
ribbonHalfButton_3.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/save.png", UriKind.RelativeOrAbsolute));
RibbonHalfButton ribbonHalfButton_4 = new RibbonHalfButton();
ribbonHalfButton_4.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/save_as.png", UriKind.RelativeOrAbsolute));
RibbonHalfButton ribbonHalfButton_5 = new RibbonHalfButton();
ribbonHalfButton_5.Image = new BitmapImage(new Uri(
@"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
+ @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
+ @"/save_all.png", UriKind.RelativeOrAbsolute));
controller.addRibbonBar((RibbonBar) homeRibbonBar);
homeRibbonBar.addRibbonGroupBox((RibbonGroupBox) clipboardGroupBox);
clipboardGroupBox.addRibbonComponent((IRibbonResizing) pasteButton);
clipboardGroupBox.addRibbonComponent((IRibbonResizing) ribbon3RowsLayout_1);
ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.top,
(IRibbonResizing) ribbonThirdLabel_1);
ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.middle,
(IRibbonResizing) ribbonThirdLabel_2);
ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.bottom,
(IRibbonResizing) ribbonThirdLabel_3);
homeRibbonBar.addRibbonGroupBox((RibbonGroupBox) controlsGroupBox);
controlsGroupBox.addRibbonComponent((IRibbonResizing) ribbon2RowsLayout_1);
ribbon2RowsLayout_1.addRibbonComponent(RibbonTwoRowsLayout.Position.top,
(IRibbonResizing) ribbonHalfButtonGroup_1);
ribbonHalfButtonGroup_1.addComponent((IRibbonHalfControl) ribbonHalfButton_1);
ribbonHalfButtonGroup_1.addComponent((IRibbonHalfControl) ribbonHalfButton_2);
ribbon2RowsLayout_1.addRibbonComponent(RibbonTwoRowsLayout.Position.bottom,
(IRibbonResizing) ribbonHalfButtonGroup_2);
ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_3);
ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_4);
ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_5);
controller.addRibbonBar((RibbonBar) insertRibbonBar);
controller.addRibbonBar((RibbonBar) reviewRibbonBar);
请注意,已修改某些行以减小文章的宽度。保存和加载按钮目前未实现。
Using the Code
通常不需要代码,因为编译后的应用程序应能正确处理当前版本的功能区库,但为完整起见仍包含在内。
Window1
是应用程序的主窗口。源代码中的用户控件是在选择堆栈元素时显示的选项面板,它们在节点被选中时生成(并相应地在选择新节点时销毁)。SelectionWindow
是一个通用的 Window
,用于从 List>String<
中选择一个项目。ResultsSourceWindow
用于显示生成的源代码;这是第三方开发的好地方,请有人添加一些语法高亮。
关注点
请注意,设置图像按钮会打开一个 Windows.Forms.OpenFileDialog
;奇怪的是,Windows Presentation Foundation 中没有打开对话框。在多个计算论坛中都注意到了这个缺陷,并被恰当地称为“一个明显的疏忽”。
已知bug
- 添加元素到功能区控件后,在调整应用程序窗口大小时,功能区/应用程序会挂起,原因未知。
- 并非所有
RibbonControl
库中的控件都受支持/现有支持完全未经测试(请在下面的评论中报告所有 bug)。
历史
版本 1.0.0.0 --- 初始构建
版本 1.0.0.1 --- 支持 RibbonControl
库的 版本 1.0.0.9
其他许可说明
请随意在您的工作中随意使用此代码,但请注意,正在使用修改后的 Code Project Open License (CPOL);基本上与标准许可证相同,只是未经事先授权,不得将此代码用于商业或非营利性商业用途。请参阅随附的源代码和演示文件中的 license.txt 或 license.pdf。