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

适用于 WinForms 的 Windows 功能区,第 11 部分 – DropDownGallery、SplitButtonGallery 和 InRibbonGallery

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (16投票s)

2010年3月2日

Ms-PL

5分钟阅读

viewsIcon

25565

downloadIcon

1426

在本文中,我将介绍如何使用功能区下拉画廊、拆分按钮画廊和功能区内画廊控件。

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

引言

在这篇文章中,我将向您展示如何使用 Windows 功能区框架提供的各种画廊。

本帖的结果是一个名为“09-Galleries”的新示例,您可以在 适用于 WinForms 的 Windows 功能区 项目页面上找到它。看起来像这样:

image

image

项目画廊 vs. 命令画廊

我们将要回顾的画廊有两种类型:项目画廊和命令画廊。在本节中,我们将了解这两者之间的区别。

项目画廊

  • 画廊项目是“简单”的项目,只有文本和图像,类似于 ComboBox 中的项目。
  • 项目有索引,并且有一个“选定项目”的概念。
  • 项目画廊支持预览。这意味着当您将鼠标悬停在某个项目上时,会收到一个“预览”通知(事件),并且在取消选择时会收到一个“取消预览”通知。
  • 项目画廊中的单个项目具有以下属性:LabelImageCategoryID

注意:ComboBox 功能区控件也是一个项目画廊。

命令画廊

  • 画廊项目实际上是命令。
  • 命令没有索引,因此没有“选定项目”的概念。
  • 命令画廊不支持预览。
  • 命令画廊中的单个项目具有以下属性:CommandIDCommandTypeCategoryID

注意:两种类型的画廊都有类别(categories)的概念,有关更多详细信息,请参阅 ComboBox 文章

画廊类型

现在我们将回顾我们拥有的三种画廊类型,每种都可以是项目画廊或命令画廊。请注意,根据 MSDN,ComboBox 也被视为一种画廊,它始终是项目画廊。由于我们已经在之前的文章中回顾了 ComboBox,这里就不再赘述。

  • DropDownGallery:只是一个按钮,点击它会显示项目列表。按钮本身没有操作。在上图的第一个图像中,最左边的控件是 DropDownGallery
  • SplitButtonGallery:两个按钮,一个用作默认操作,另一个按钮打开项目列表。在上图的第二个图像中,中间的控件是 SplitButtonGallery
  • 注意:我们在 之前的文章 中已经看到,DropDownSplitButton 的主要区别在于 SplitButton 有一个默认项。

  • InRibbonGallery:项目显示在功能区内部,无需按钮。在上图的图像中,最右边的控件是 InRibbonGallery

命令空间

为了完整起见,您还应该知道一个附加功能,这三种画廊都有一个命令空间。这是控件底部的一个区域,其中包含静态定义的命令。在上图的第一个图像中,DropDownGallery 在其命令空间中定义了一个按钮。

使用画廊

在接下来的部分,我将展示如何定义功能区标记中的画廊,并使用新的辅助类轻松地对它们进行操作。请注意,由于画廊有很多选项,我将只演示一个代表性的子集。

使用 DropDownGallery - 功能区标记

在这里,我将展示如何使用 DropDownGallery 作为带有命令空间的**项目画廊**。命令部分

<Application.Commands>
  <Command Name='cmdTabMain' Id='1000' LabelTitle='Main' />
  <Command Name='cmdGroupDropDownGallery' Id='1001' LabelTitle='Drop Down' />
  <Command Name='cmdDropDownGallery' Id='1002' LabelTitle='Size' >
    <Command.LargeImages>
      <Image>Res/Open32.bmp</Image>
    </Command.LargeImages>
    <Command.SmallImages>
      <Image>Res/Open16.bmp</Image>
    </Command.SmallImages>
  </Command>
  <Command Name='cmdCommandSpace' Id='1003' LabelTitle='Command Space' >
    <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 CommandName='cmdTabMain'>
        <Group CommandName='cmdGroupDropDownGallery' SizeDefinition='OneButton'>
          <DropDownGallery CommandName='cmdDropDownGallery'
                           TextPosition='Hide'
                           Type='Items'>
            <DropDownGallery.MenuLayout>
              <FlowMenuLayout Columns='1' Rows='5' Gripper='None' />
            </DropDownGallery.MenuLayout>
            <DropDownGallery.MenuGroups>
              <MenuGroup>
                <Button CommandName='cmdCommandSpace' />
              </MenuGroup>
            </DropDownGallery.MenuGroups>
          </DropDownGallery>
        </Group>
        ...
      </Tab>
    </Ribbon.Tabs>
  </Ribbon>
</Application.Views>

在视图部分,您定义 DropDownGallery 的使用以及其布局(您想要的列数和行数)和命令空间。使此画廊成为项目画廊的是将 Type 属性设置为 Items。有关 DropDownGallery 属性的更多详细信息,请参阅 MSDN

使用 DropDownGallery - 代码隐藏

创建 RibbonLib.DropDownGallery 辅助类的实例并注册其部分事件。

private Ribbon _ribbon = new Ribbon();
private RibbonDropDownGallery _dropDownGallery;

public Form1()
{
    InitializeComponent();

    _dropDownGallery = new RibbonDropDownGallery(_ribbon, 
                      (uint)RibbonMarkupCommands.cmdDropDownGallery);

    _dropDownGallery.OnExecute += new OnExecuteEventHandler(_dropDownGallery_OnExecute);
    _dropDownGallery.OnPreview += new OnPreviewEventHandler(_dropDownGallery_OnPreview);
    _dropDownGallery.OnCancelPreview += 
                     new OnCancelPreviewEventHandler(_dropDownGallery_OnCancelPreview);
}

void _dropDownGallery_OnCancelPreview(PropertyKeyRef key, 
      PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
    Console.WriteLine("DropDownGallery::OnCancelPreview");
}

void _dropDownGallery_OnPreview(PropertyKeyRef key, 
     PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
    Console.WriteLine("DropDownGallery::OnPreview");
}

void _dropDownGallery_OnExecute(PropertyKeyRef key, 
     PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
    Console.WriteLine("DropDownGallery::OnExecute");
}

DropDownGallery 添加项目

private void Form1_Load(object sender, EventArgs e)
{
    _ribbon.InitFramework(this);

    FillDropDownGallery();
}

private void FillDropDownGallery()
{
    // set label
    _dropDownGallery.Label = "Size";

    // set _dropDownGallery items
    IUICollection itemsSource = _dropDownGallery.ItemsSource;
    itemsSource.Clear();
    foreach (Image image in imageListLines.Images)
    {
        itemsSource.Add(new GalleryItemPropertySet() 
              {
                  ItemImage = _ribbon.ConvertToUIImage((Bitmap)image)
              });
    }
}

请注意,我在这里使用了一个标准的 ImageList 控件来为 DropDownGallery 提供位图。GalleryItemPropertySet 是一个辅助类,表示项目画廊中的单个项目。

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

最后,将 IUICommandHandler.ExecuteIUICommandHandler.UpdateProperty 方法与 DropDownGallery 类中这些方法的实现连接起来。

public HRESULT Execute(uint commandId, UI_ExecutionVerb verb, ref PropertyKey key, 
                       ref PropVariant currentValue, 
                       IUISimplePropertySet commandExecutionProperties)
{
    if (commandId == (uint)RibbonMarkupCommands.cmdDropDownGallery)
    {
        return _dropDownGallery.Execute(verb, ref key, ref currentValue,
                                        commandExecutionProperties);
    }
    return HRESULT.S_OK;
}

public HRESULT UpdateProperty(uint commandId, ref PropertyKey key, 
                              ref PropVariant currentValue, ref PropVariant newValue)
{
    if (commandId == (uint)RibbonMarkupCommands.cmdDropDownGallery)
    {
        return _dropDownGallery.UpdateProperty(ref key, ref currentValue, ref newValue);
    }
    return HRESULT.S_OK;
}

使用 SplitButtonGallery - 功能区标记

在这里,我将展示如何使用 SplitButtonGallery 作为**命令画廊**。这是命令部分。

<Command Name='cmdGroupSplitButtonGallery' Id='1004' LabelTitle='Split Button' />
<Command Name='cmdSplitButtonGallery' Id='1005' LabelTitle='Brushes' >
  <Command.LargeImages>
    <Image>Res/Brush1.bmp</Image>
  </Command.LargeImages>
</Command>

视图部分

...
<Group CommandName="cmdGroupSplitButtonGallery" SizeDefinition="OneButton">
  <SplitButtonGallery CommandName="cmdSplitButtonGallery"
                      TextPosition="Hide" Type="Commands" HasLargeItems="true">
    <SplitButtonGallery.MenuLayout>
      <FlowMenuLayout Columns="4" Rows="3" Gripper="None"/>
    </SplitButtonGallery.MenuLayout>
  </SplitButtonGallery>
</Group>
...

在视图部分,您定义 SplitButtonGallery 的使用以及其布局(您想要的列数和行数),以及可选的命令空间。使此画廊成为命令画廊的是将 Type 属性设置为 Commands。有关 SplitButtonGallery 属性的更多详细信息,请参阅 MSDN

使用 SplitButtonGallery - 代码隐藏

创建 RibbonLib.SplitButtonGallery 辅助类的实例。

private Ribbon _ribbon = new Ribbon();
private RibbonSplitButtonGallery _splitButtonGallery;
private RibbonButton[] _buttons;

public Form1()
{
    InitializeComponent();

    _splitButtonGallery = new RibbonSplitButtonGallery(_ribbon, 
                (uint)RibbonMarkupCommands.cmdSplitButtonGallery);
}

SplitButtonGallery 添加项目

private void Form1_Load(object sender, EventArgs e)
{
    _ribbon.InitFramework(this);

    FillSplitButtonGallery();
}

private void FillSplitButtonGallery()
{
    // set label
    _splitButtonGallery.Label = "Brushes";

    // prepare helper classes for commands
    _buttons = new RibbonButton[imageListBrushes.Images.Count];
    uint i;
    for (i = 0; i < _buttons.Length; ++i)
    {
        _buttons[i] = new RibbonButton(_ribbon, 2000 + i)
               {
                   Label = "Label " + i.ToString(),
                   LargeImage = _ribbon.ConvertToUIImage(
                                 (Bitmap) imageListBrushes.Images[(int) i])
               };
    }

    // set _splitButtonGallery categories
    IUICollection categories = _splitButtonGallery.Categories;
    categories.Clear();
    categories.Add(new GalleryItemPropertySet() { Label = "Category 1", CategoryID = 1 });

    // set _splitButtonGallery items
    IUICollection itemsSource = _splitButtonGallery.ItemsSource;
    itemsSource.Clear();
    i = 0;
    foreach (Image image in imageListBrushes.Images)
    {
        itemsSource.Add(new GalleryCommandPropertySet()
               {
                   CommandID = 2000 + i++,
                   CommandType = CommandType.Action,
                   CategoryID = 1
               });
    }

    // add default item to items collection
    itemsSource.Add(new GalleryCommandPropertySet()
               {
                   CommandID = (uint)RibbonMarkupCommands.cmdSplitButtonGallery,
                   CommandType = CommandType.Action,
                   CategoryID = 1
               });
}

GalleryCommandPropertySet 是一个辅助类,表示命令画廊中的单个项目。

重要提示:如果您不将默认项添加到 SplitButtonGallery 的项目列表中,项目将出现两次!这很可能是一个 bug。

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

最后,将 IUICommandHandler.ExecuteIUICommandHandler.UpdateProperty 方法与 SplitButtonGalleryButton 类中这些方法的实现连接起来。

public HRESULT Execute(uint commandId, UI_ExecutionVerb verb, ref PropertyKey key, 
                       ref PropVariant currentValue, 
                       IUISimplePropertySet commandExecutionProperties)
{
    if (commandId == (uint)RibbonMarkupCommands.cmdSplitButtonGallery)
    {
        return _splitButtonGallery.Execute(verb, ref key, ref currentValue,
                                           commandExecutionProperties);
    }
    else if (commandId >= 2000)
    {
        return _buttons[commandId - 2000].Execute(verb, ref key, ref currentValue,
                                                  commandExecutionProperties);
    }
    return HRESULT.S_OK;
}

public HRESULT UpdateProperty(uint commandId, ref PropertyKey key, 
                              ref PropVariant currentValue, ref PropVariant newValue)
{
    if (commandId == (uint)RibbonMarkupCommands.cmdSplitButtonGallery)
    {
        return _splitButtonGallery.UpdateProperty(ref key, ref currentValue, 
                                                  ref newValue);
    }
    else if (commandId >= 2000)
    {
        return _buttons[commandId - 2000].UpdateProperty(ref key, ref currentValue, 
                                                         ref newValue);
    }
    return HRESULT.S_OK;
}

请注意动态添加的命令的处理。

使用 InRibbonGallery - 功能区标记

在这里,我将展示如何使用 InRibbonGallery 作为**项目画廊**。这是命令部分。

<Command Name='cmdGroupInRibbonGallery' Id='1006' LabelTitle='In Ribbon' />
<Command Name='cmdInRibbonGallery' Id='1007' />

视图部分

...
<Group CommandName="cmdGroupInRibbonGallery" SizeDefinition="OneInRibbonGallery">
  <InRibbonGallery CommandName="cmdInRibbonGallery" Type="Items"
                   MaxRows="3" MaxColumns="7">
  </InRibbonGallery>
</Group>
...

在视图部分,您定义 InRibbonGallery 的使用及其布局。请注意,InRibbonGallery 对其项目的布局方式有更多控制。有关 InRibbonGallery 属性的更多详细信息,请参阅 MSDN

使用 InRibbonGallery - 代码隐藏

代码与 DropDownGallery 代码类似。这篇文章已经够长了。

目前就到这里为止。

© . All rights reserved.