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

Windows Ribbon for WinForms, 第 14 部分 – FontControl

starIconstarIconstarIconstarIconstarIcon

5.00/5 (10投票s)

2010年3月2日

Ms-PL

4分钟阅读

viewsIcon

28455

downloadIcon

1468

在本文中,我将介绍如何使用 Ribbon 字体控件。

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

Windows Ribbon for WinForms 库现已支持 FontControl 控件。本文的成果是项目中又一个示例,“12-FontControl”,可以在项目网站上找到。

image

FontControl 控件

FontControl 是 Windows Ribbon Framework 提供的另一个特殊控件。它允许您选择字体系列、大小、颜色和相关效果。它有三种类型,每种类型都比其他类型提供更多的功能。

  • 仅字体
  • 带颜色的字体
  • 富文本字体

image

请查阅 MSDN 上的 Font Control 以了解各类型之间差异的详细信息。

FontControl 属性

以下是 FontControl 控件特有的属性列表。其余属性已在之前的文章中介绍过。

  • FontProperties - 此属性类型为 IPropertyStore,包含所有字体相关的属性,例如 SizeBoldUnderline 等。在 FontControl 辅助类中,我内部使用此属性来访问其他属性,但不对用户公开,因为它除了作为访问其他属性的入口点外没有其他用途。属性标识符:UI_PKEY_FontProperties
  • ChangedProperties - 此属性包含所有最近更改的属性。FontControl 不公开它,但在 Execute / Preview / CancelPreview 事件中将其作为参数之一提供。例如,如果您单击“粗体”按钮,将调用 Execute 事件,并且此属性将仅包含 Bold 属性。属性标识符:UI_PKEY_FontProperties_ChangedProperties
  • Family - 所选的字体系列名称。属性标识符:UI_PKEY_FontProperties_Family
  • Size - 字体的大小。属性标识符:UI_PKEY_FontProperties_Size
  • Bold - 指示是否选择了粗体的标志。属性标识符:UI_PKEY_FontProperties_Bold
  • Italic - 指示是否选择了斜体的标志。属性标识符:UI_PKEY_FontProperties_Italic
  • Underline - 指示是否选择了下划线的标志。属性标识符:UI_PKEY_FontProperties_Underline
  • Strikethrough - 指示是否选择了删除线的标志(有时称为删除线)。属性标识符:UI_PKEY_FontProperties_Strikethrough
  • VerticalPositioning - 指示选中的上标或下标按钮(如果有)的标志。属性标识符:UI_PKEY_FontProperties_VerticalPositioning
  • ForegroundColor - 当 ForegroundColorType 设置为 RGB 时包含文本颜色。FontControl 辅助类将此属性公开为 .NET Color,并内部处理与 COLORREF 结构之间的转换。属性标识符:UI_PKEY_FontProperties_ForegroundColor
  • ForegroundColorType - 文本颜色类型。有效值是 RGBAutomatic。如果选择了 RGB,用户应从 ForegroundColor 属性获取颜色。如果选择了 Automatic,用户应使用 SystemColors.WindowTextFontControl 辅助类不公开 ForegroundColorType 属性。相反,它在内部实现了颜色选择算法(即,根据类型属性返回正确的颜色)。属性标识符:UI_PKEY_FontProperties_ForegroundColorType
  • BackgroundColor - 当 BackgroundColorType 设置为 RGB 时包含背景颜色。FontControl 辅助类将此属性公开为 .NET Color,并内部处理与 COLORREF 结构之间的转换。属性标识符:UI_PKEY_FontProperties_BackgroundColor
  • BackgroundColorType - 背景颜色类型。有效值是 RGBNoColor。如果选择了 RGB,用户应从 BackgroundColor 属性获取颜色。如果选择了 NoColor,用户应使用 SystemColors.WindowFontControl 辅助类不公开 ForegroundColorType 属性。相反,它在内部实现了颜色选择算法(即,根据类型属性返回正确的颜色)。属性标识符:UI_PKEY_FontProperties_BackgroundColorType
  • DeltaSize - 指示是否按下了“增大字体”或“减小字体”按钮。此属性仅作为 ChangedProperties 属性的一部分可用,并且不被 FontControl 辅助类公开。属性标识符:UI_PKEY_FontProperties_DeltaSize

使用 FontControl - Ribbon 标记

命令和视图部分

<?xml version='1.0' encoding='utf-8'?>
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
    <Application.Commands>
    <Command Name="cmdTabMain" Id="1001" LabelTitle="Main" />
    <Command Name="cmdGroupRichFont" Id="1002" LabelTitle="Rich Font" />
    <Command Name="cmdRichFont" Id="1003" Keytip="F" />
  </Application.Commands>

    <Application.Views>
        <Ribbon>
      <Ribbon.Tabs>
        <Tab CommandName="cmdTabMain">
          <Group CommandName="cmdGroupRichFont" SizeDefinition="OneFontControl">
            <FontControl CommandName="cmdRichFont" FontType="RichFont" />
          </Group>
        </Tab>
      </Ribbon.Tabs>
    </Ribbon>
    </Application.Views>
</Application>

有关 FontControl 属性的更多详细信息,请参阅 MSDN。

使用 FontControl - 后台代码

以下代码展示了使用 Ribbon FontControl 的基本步骤,该控件与标准 .NET RichTextBox 控件中选定的文本保持同步。

  • 初始化
  • private Ribbon _ribbon;
    private RibbonFontControl _richFont;
    
    public Form1()
    {
        InitializeComponent();
    
        _ribbon = new Ribbon();
        _richFont = new RibbonFontControl(_ribbon, 
                        (uint)RibbonMarkupCommands.cmdRichFont);
    
        _richFont.OnExecute += new OnExecuteEventHandler(_richFont_OnExecute);
        _richFont.OnPreview += new OnPreviewEventHandler(_richFont_OnPreview);
        _richFont.OnCancelPreview += 
            new OnCancelPreviewEventHandler(_richFont_OnCancelPreview);
    }
  • FontControl 发生更改时设置 RichTextBox 属性
  • void _richFont_OnExecute(PropertyKeyRef key, PropVariantRef currentValue, 
                             IUISimplePropertySet commandExecutionProperties)
    {
        // skip if selected font is not valid
        if ((_richFont.Family == null) ||
             (_richFont.Family.Trim() == string.Empty) ||
             (_richFont.Size == 0))
        {
            return;
        }
    
        // prepare font style
        FontStyle fontStyle = FontStyle.Regular;
        if (_richFont.Bold == FontProperties.Set)
        {
            fontStyle |= FontStyle.Bold;
        }
        if (_richFont.Italic == FontProperties.Set)
        {
            fontStyle |= FontStyle.Italic;
        }
        if (_richFont.Underline == FontUnderline.Set)
        {
            fontStyle |= FontStyle.Underline;
        }
        if (_richFont.Strikethrough == FontProperties.Set)
        {
            fontStyle |= FontStyle.Strikeout;
        }
    
        // set selected font
        richTextBox1.SelectionFont = 
            new Font(_richFont.Family, (float)_richFont.Size, fontStyle);
    
        // set selected colors
        richTextBox1.SelectionColor = _richFont.ForegroundColor;
        richTextBox1.SelectionBackColor = _richFont.BackgroundColor;
    
        // set subscript / superscript
        switch (_richFont.VerticalPositioning)
        {
            case FontVerticalPosition.NotSet:
                richTextBox1.SelectionCharOffset = 0;
                break;
    
            case FontVerticalPosition.SuperScript:
                richTextBox1.SelectionCharOffset = 10;
                break;
    
            case FontVerticalPosition.SubScript:
                richTextBox1.SelectionCharOffset = -10;
                break;
        }
    }

    注意:RichTextBox 原生不支持上标和下标。它支持设置字符偏移量,我就是用这个来模拟所需行为的。

  • 添加对更改字体系列和字体大小时预览的支持
  • void _richFont_OnPreview(PropertyKeyRef key, PropVariantRef currentValue, 
                             IUISimplePropertySet commandExecutionProperties)
    {
        PropVariant propChangesProperties;
        commandExecutionProperties.GetValue(
            ref RibbonProperties.FontProperties_ChangedProperties, 
            out propChangesProperties);
        IPropertyStore changedProperties = (IPropertyStore)propChangesProperties.Value;
    
        UpdateRichTextBox(changedProperties);
    }
    
    void _richFont_OnCancelPreview(PropertyKeyRef key, PropVariantRef currentValue, 
                                   IUISimplePropertySet commandExecutionProperties)
    {
        IPropertyStore fontProperties = 
                      (IPropertyStore)currentValue.PropVariant.Value;
    
        UpdateRichTextBox(fontProperties);
    }
    
    private void UpdateRichTextBox(IPropertyStore propertyStore)
    {
        RibbonLib.FontPropertyStore fontPropertyStore = 
                  new RibbonLib.FontPropertyStore(propertyStore);
        PropVariant propValue;
    
        FontStyle fontStyle = richTextBox1.SelectionFont.Style;
        string family = richTextBox1.SelectionFont.FontFamily.Name;
        float size = richTextBox1.SelectionFont.Size;
    
        if (propertyStore.GetValue(ref RibbonProperties.FontProperties_Family, 
                                   out propValue) == HRESULT.S_OK)
        {
            family = fontPropertyStore.Family;
        }
        if (propertyStore.GetValue(ref RibbonProperties.FontProperties_Size, 
                                   out propValue) == HRESULT.S_OK)
        {
            size = (float)fontPropertyStore.Size;
        }
    
        richTextBox1.SelectionFont = new Font(family, size, fontStyle);
    }

    注意:只有字体系列和字体大小应支持预览,因为只有它们附带组合框。

  • RichTextBox 中的文本选择发生更改时更新 FontControl
  • private void richTextBox1_SelectionChanged(object sender, EventArgs e)
    {
        // update font control font
        if (richTextBox1.SelectionFont != null)
        {
            _richFont.Family = richTextBox1.SelectionFont.FontFamily.Name;
            _richFont.Size = (decimal)richTextBox1.SelectionFont.Size;
            _richFont.Bold = richTextBox1.SelectionFont.Bold ? 
                             FontProperties.Set : FontProperties.NotSet;
            _richFont.Italic = richTextBox1.SelectionFont.Italic ? 
                             FontProperties.Set : FontProperties.NotSet;
            _richFont.Underline = richTextBox1.SelectionFont.Underline ? 
                             FontUnderline.Set : FontUnderline.NotSet;
            _richFont.Strikethrough = richTextBox1.SelectionFont.Strikeout ? 
                             FontProperties.Set : FontProperties.NotSet;
        }
        else
        {
            _richFont.Family = string.Empty;
            _richFont.Size = 0;
            _richFont.Bold = FontProperties.NotAvailable;
            _richFont.Italic = FontProperties.NotAvailable;
            _richFont.Underline = FontUnderline.NotAvailable;
            _richFont.Strikethrough = FontProperties.NotAvailable;
        }
    
        // update font control colors
        _richFont.ForegroundColor = richTextBox1.SelectionColor;
        _richFont.BackgroundColor = richTextBox1.SelectionBackColor;
    
        // update font control vertical positioning
        switch (richTextBox1.SelectionCharOffset)
        { 
            case 0:
                _richFont.VerticalPositioning = FontVerticalPosition.NotSet;
                break;
    
            case 10:
                _richFont.VerticalPositioning = FontVerticalPosition.SuperScript;
                break;
    
            case -10:
                _richFont.VerticalPositioning = FontVerticalPosition.SubScript;
                break;
        }
    }

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

  • IUICommandHandler 实现与辅助类实现连接起来
  • public HRESULT Execute(uint commandId, ExecutionVerb verb, PropertyKeyRef key, 
                           PropVariantRef currentValue, 
                           IUISimplePropertySet commandExecutionProperties)
    {
        switch (commandId)
        {
            case (uint)RibbonMarkupCommands.cmdRichFont:
                _richFont.Execute(verb, key, currentValue, 
                                  commandExecutionProperties);
                break;
        }
    
        return HRESULT.S_OK;
    }
    
    public HRESULT UpdateProperty(uint commandId, ref PropertyKey key, 
                                  PropVariantRef currentValue, 
                                  ref PropVariant newValue)
    {
        switch (commandId)
        {
            case (uint)RibbonMarkupCommands.cmdRichFont:
                _richFont.UpdateProperty(ref key, currentValue, ref newValue);
                break;
        }
    
        return HRESULT.S_OK;
    }

目前就到这里为止。

© . All rights reserved.