65.9K
CodeProject 正在变化。 阅读更多。
Home

WinForms 版 Windows 功能区,第四部分 - 带按钮的应用程序菜单

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2010年3月2日

Ms-PL

4分钟阅读

viewsIcon

27582

downloadIcon

1996

在本文中,我将介绍如何使用功能区应用程序菜单。

这系列 CodeProject 文章基于我首先在我的 博客上发表的一系列帖子。

在我们开始使用功能区特性之前,必须先了解功能区标记的基础知识。

命令和视图

命令是一个由数字标识的操作,它可以是打开“另存为”对话框、打印当前文档、关闭应用程序等——任何您可以在函数调用中完成的操作。

视图是 [通常几个] 命令的图形表示。它定义了用于激活命令的控件类型及其在屏幕上的大小、顺序和布局。

因此,使用命令和视图实际上只是 MVC 设计模式的另一种实现,它允许我们将业务逻辑与表示逻辑分开。

现在我们将创建一个新的带有功能区的 WinForms 应用程序,该应用程序使用带有简单按钮的应用程序菜单。我们从一个已经包含功能区支持的空 WinForms 项目开始(有关详细信息,请参阅上一篇文章)。在接下来的部分中,我将解释

  • 功能区标记的命令部分
  • 功能区标记的视图部分
  • 代码后台,响应功能区事件

一如既往,全部代码可在 windowsribbon.codeplex.com 获取。

通用标记回顾

提醒一下,我们基本的功能区标记看起来像这样

<?xml version='1.0' encoding='utf-8'?>
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
  <Application.Commands>
  </Application.Commands>

  <Application.Views>
    <Ribbon>
    </Ribbon>
  </Application.Views>
</Application>

在功能区标记中定义命令

以下是在功能区标记中定义的一些命令

<Application.Commands>
  <Command Name="cmdButtonNew"
           Id="1001"
           LabelTitle="&New"
           LabelDescription="New Description"
           TooltipTitle="New"
           TooltipDescription="Create a new image.">
    <Command.LargeImages>
      <Image>Res/New32.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
      <Image>Res/New16.bmp</Image>
    </Command.SmallImages>
  </Command>
  
  <Command Name="cmdButtonOpen"
           Id="1002"
           LabelTitle="Open"
           LabelDescription="Open Description"
           TooltipTitle="Open"
           TooltipDescription="Open an existing image.">
    <Command.LargeImages>
      <Image>Res/Open32.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
      <Image>Res/Open16.bmp</Image>
    </Command.SmallImages>
  </Command>
  
  <Command Name="cmdButtonSave"
           Id="1003"
           LabelTitle="Save"
           LabelDescription="Save Description"
           TooltipTitle="Save"
           TooltipDescription="Save the current image.">
    <Command.LargeImages>
      <Image>Res/Save32.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
      <Image>Res/Save16.bmp</Image>
    </Command.SmallImages>
  </Command>
  
  <Command Name="cmdButtonExit"
           Id="1004"
           LabelTitle="Exit"
           LabelDescription="Exit Description"
           TooltipTitle="Exit"
           TooltipDescription="Exit application.">
    <Command.LargeImages>
      <Image>Res/Exit32.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
      <Image>Res/Exit16.bmp</Image>
    </Command.SmallImages>
  </Command>
</Application.Commands>

说明:这里我们定义了 4 个不同的命令。每个命令的属性都通过 XML 属性或子元素进行设置。我们使用以下属性(完整列表可在 MSDN 的“Commands and Resources”中找到):

  • Name – 此名称稍后在视图部分用于引用此命令
  • Id – 这是命令的 ID。当发生命令事件时,我们可以在代码中获取它。
  • LabelTitle – 命令的标签标题
  • LabelDescription – 命令的标签描述
  • TooltipTitle – 命令的工具提示标题
  • TooltipDescription – 命令的工具提示描述
  • LargeImages – 命令的大图像文件名,通常为 32x32 像素
  • SmallImages – 命令的小图像文件名,通常为 16x16 像素

为菜单项设置快捷方式

通过在 LabelTitle 中要在快捷方式的字母前添加“&”(类似于“旧”菜单系统中的快捷方式),即可为菜单项设置键盘快捷方式,例如,请参阅“New”命令的 LabelTitle

关于功能区标记中图像资源的几点说明

标记中定义的(例如 LargeImages SmallImages 元素中的)文件名,应该是有效的文件名路径(相对或绝对路径),否则资源编译器(rc.exe)将输出编译错误:“error RC2135: file not found: <filename>”。

图像文件格式应为 BMP,32 BPP ARGB 像素格式。许多图像编辑程序,如 Microsoft Paint,在保存时不会保留最高位的 8 位 alpha 通道,从而只创建 24 位图像,结果将导致图像根本不显示。

更新(2009 年 11 月 18 日)convert2bmp 是一个工具,可以帮助您将图像转换为所需格式。

在两个图像元素下,您可以放置多个不同尺寸的图像文件,功能区框架将根据当前的 DPI 设置选择最佳尺寸。对于我们普通用户来说,设置 32x32 和 16x16 两种尺寸的图像应该足够了。有关更多信息,请参阅 MSDN 上的“Specifying Ribbon Image Resources”。

在功能区标记中定义视图

以下是我们功能区标记的 views 部分定义

<Application.Views>
  <Ribbon>
    <Ribbon.ApplicationMenu>
      <ApplicationMenu>
        <MenuGroup>
          <Button CommandName='cmdButtonNew' />
          <Button CommandName='cmdButtonOpen' />
          <Button CommandName='cmdButtonSave' />
        </MenuGroup>
        <MenuGroup>
          <Button CommandName='cmdButtonExit' />
        </MenuGroup>
      </ApplicationMenu>
    </Ribbon.ApplicationMenu>
  </Ribbon>
</Application.Views>

说明:这里我们定义了一个应用程序菜单,其中包含两个菜单组和 4 个按钮。按钮的 CommandName 属性指向该按钮单击时应触发的命令。

处理功能区事件

在这里,我们将看到如何处理单击我们其中一个菜单按钮的事件。

以下代码应放在我们的主窗体代码文件(在我的示例中为 form1.cs)中

public enum RibbonMarkupCommands : uint 
{
     cmdApplicationMenu = 1000,
     cmdButtonNew = 1001,
     cmdButtonOpen = 1002,
     cmdButtonSave = 1003,
     cmdButtonExit = 1004,
}

这只是一个辅助 enum,使代码更易读。每个命令 ID 都获得一个可读的符号。
重要部分是我们对 IUICommandHandler.Execute 函数的实现

public HRESULT Execute(uint commandId, UI_ExecutionVerb verb, 
	ref PropertyKey key, ref PropVariant currentValue, 
	IUISimplePropertySet commandExecutionProperties)
{
    if ((commandId == (uint)RibbonMarkupCommands.cmdButtonNew) &&
        (verb == UI_ExecutionVerb.Execute))
    {
        MessageBox.Show("new button pressed");
    }
    return HRESULT.S_OK;
}

更新(2009 年 11 月 18 日):现在处理功能区事件就像处理常规 .NET 事件一样简单。用户不再需要实现 IUICommandHandler

private Ribbon _ribbon;
private RibbonButton _buttonNew;

public Form1()
{
    InitializeComponent();

    _ribbon = new Ribbon();
    _buttonNew = new RibbonButton(_ribbon, (uint)RibbonMarkupCommands.cmdButtonNew);

    _buttonNew.OnExecute += new OnExecuteEventHandler(_buttonNew_OnExecute);
}

void _buttonNew_OnExecute(PropertyKeyRef key, 
	PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
    MessageBox.Show("new button pressed");
}

自然,我们在文件开头添加了

using RibbonLib;
using RibbonLib.Controls;
using RibbonLib.Controls.Events;
using RibbonLib.Interop;

这样,您就拥有了一个带有功能区应用程序菜单的 WinForms 应用程序。

image

暂时就到这里,
Arik Poznanski。

© . All rights reserved.