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

Windows Ribbon for WinForms,第 12 部分 – CheckBox 和 ToggleButton

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2010年3月2日

Ms-PL

3分钟阅读

viewsIcon

26737

downloadIcon

1292

在本文中,我将介绍如何使用功能区复选框和切换按钮控件。

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

复选框和切换按钮

简而言之,我增加了对 CheckBoxToggleButton 功能区控件的支持。一个名为 10-CheckBox 的新示例已添加到 项目站点。结果如下所示

image

使用 CheckBox 和 ToggleButton - 功能区标记

命令和视图部分

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

    <Command Name="cmdToggleButton"
             Id="1002"
             LabelTitle="Toggle Button">
      <Command.LargeImages>
        <Image>Res/Open32.bmp</Image>
      </Command.LargeImages>
      <Command.SmallImages>
        <Image>Res/Open16.bmp</Image>
      </Command.SmallImages>
    </Command>

    <Command Name="cmdCheckBox"
             Id="1003"
             LabelTitle="Check Box">
      <Command.LargeImages>
        <Image>Res/Save32.bmp</Image>
      </Command.LargeImages>
      <Command.SmallImages>
        <Image>Res/Save16.bmp</Image>
      </Command.SmallImages>
    </Command>

  </Application.Commands>

  <Application.Views>
    <Ribbon>
      <Ribbon.Tabs>
        <Tab>
          <Group>
            <ToggleButton CommandName="cmdToggleButton" />
          </Group>
          <Group CommandName="cmdGroupCheckBox">
            <CheckBox CommandName="cmdCheckBox" />
          </Group>
        </Tab>
      </Ribbon.Tabs>
    </Ribbon>
  </Application.Views>
</Application>

使用 CheckBox 和 ToggleButton - 代码隐藏

初始化

private Ribbon _ribbon;
private RibbonToggleButton _toggleButton;
private RibbonCheckBox _checkBox;

public Form1()
{
  InitializeComponent();

  _ribbon = new Ribbon();
  _toggleButton = new RibbonToggleButton(_ribbon, 
                       (uint)RibbonMarkupCommands.cmdToggleButton);
  _checkBox = new RibbonLib.Controls.RibbonCheckBox(_ribbon, 
                   (uint)RibbonMarkupCommands.cmdCheckBox);

  _button.OnExecute += new OnExecuteEventHandler(_button_OnExecute);
}

IUICommandHandler 实现与辅助类实现连接起来:[如果这是你第一次看到这个,你真的应该查看之前的文章..]

public HRESULT Execute(uint commandId, RibbonLib.Interop.UI_ExecutionVerb verb, 
                        ref PropertyKey key, ref PropVariant currentValue, 
                        IUISimplePropertySet commandExecutionProperties)
{
     switch (commandId)
     {
         case (uint)RibbonMarkupCommands.cmdToggleButton:
             _toggleButton.Execute(verb, ref key, ref currentValue, 
                                   commandExecutionProperties);
             break;

         case (uint)RibbonMarkupCommands.cmdCheckBox:
             _checkBox.Execute(verb, ref key, ref currentValue, 
                               commandExecutionProperties);
             break;
     }

     return HRESULT.S_OK;
}

public HRESULT UpdateProperty(uint commandId, ref PropertyKey key, 
                               ref PropVariant currentValue, 
                               ref PropVariant newValue)
{
     switch (commandId)
     {
         case (uint)RibbonMarkupCommands.cmdToggleButton:
             _toggleButton.UpdateProperty(ref key, ref currentValue, ref newValue);
             break;

         case (uint)RibbonMarkupCommands.cmdCheckBox:
             _checkBox.UpdateProperty(ref key, ref currentValue, ref newValue);
             break;
     }

     return HRESULT.S_OK;
}

更新 (2009 年 11 月 18 日):Ribbon 类更新版本提供了 IUICommandHandler 的实现,因此用户不再需要实现 ExecuteUpdateProperty 方法。

获取/设置复选框状态

void _button_OnExecute(ref PropertyKey key, ref PropVariant currentValue, 
           IUISimplePropertySet commandExecutionProperties)
{
  MessageBox.Show("checkbox check status is: " + _checkBox.BooleanValue.ToString());
}

WinForms 库的 Windows Ribbon - 内部设计问题

这篇文章的其余部分非常无聊。它讨论了我功能区库实现的内部细节。这对于库的用户来说没有任何改变。而且,它与复选框功能无关。

既然现在只剩下我一个人,我就可以讨论库的一些内部细节了。我刚刚对功能区库进行了重大重构。

功能区库由以下部分组成

  • Windows Ribbon Framework API 包装器
  • 主要功能区类
  • 不同功能区控件的辅助类,例如按钮、组合框、下拉库等。

在旧版本的 RibbonLib 中,控件辅助类有很多重复的代码。例如,每个带有附加图像的控件(LargeImageSmallImage、... 属性)都需要以相同的方式处理这些图像(操作内部变量,通知父功能区图像已失效等)。现在,我不知道你怎么样,但每当我复制粘贴代码时,我总是有一种奇怪的感觉,觉得有些地方不对劲。所以在几个示例项目之后,我再也受不了了,决定重新设计这部分。

我所做的是将通用代码封装在类中,因此它们可以在多个控件中重复使用,而无需复制代码。

因此,现在,每个功能区控件都由几个属性提供程序(如 ImagePropertiesProviderTooltipPropertiesProvider)和事件提供程序(如 ExeciteEventsProviderPreviewEventsProvider)组成。

注意:以下句子很难,但之后会有一个例子,所以要坚强。

每个提供程序组件都有自己的接口,使用控件也通过将执行委托给该组件来实现该接口。

例如,我有一个 ImagePropertiesProvider 类,它实现了接口 IImagePropertiesProvider,它公开了四个图像属性(LargeImageSmallImage、..)。在我的 Button 辅助类中,我创建了一个 ImagePropertiesProvider 类型的成员变量,并使 Button 类也通过调用成员变量上的相应方法来实现 IImagePropertiesProvider

这是多个继承确实缺失的情况之一。作为替代方案,我所做的是使用接口的多重继承、聚合和委托模式。所以控件仍然有一些重复的代码(委托代码),但这段代码真的很简单,没有任何逻辑。

此外,每个功能区控件都有需要根据其公开的属性和事件实现的 ExecuteUpdateProperty 方法。所以我做了一个通用实现,它驻留在 BaseRibbonControl 类中,它在已注册的提供程序之一中搜索属性或事件的实现,从而简化了每个控件中的这段代码(现在它不存在了,这是我所知道的最简单的方式)。

所有这些变化的结果是

  • 更短的代码,减少了重复。
  • 开发新的辅助类非常简单。
  • 酷的类图..
属性提供程序类图

事件提供程序类图

功能区控件类图

目前就到这里为止。

© . All rights reserved.