Windows Ribbon for WinForms, 第 14 部分 – FontControl





5.00/5 (10投票s)
在本文中,我将介绍如何使用 Ribbon 字体控件。
这系列 CodeProject 文章基于我首先在我的 博客上发表的一系列帖子。
Windows Ribbon for WinForms 库现已支持 FontControl
控件。本文的成果是项目中又一个示例,“12-FontControl”,可以在项目网站上找到。
FontControl 控件
FontControl 是 Windows Ribbon Framework 提供的另一个特殊控件。它允许您选择字体系列、大小、颜色和相关效果。它有三种类型,每种类型都比其他类型提供更多的功能。
- 仅字体
- 带颜色的字体
- 富文本字体
请查阅 MSDN 上的 Font Control 以了解各类型之间差异的详细信息。
FontControl 属性
以下是 FontControl
控件特有的属性列表。其余属性已在之前的文章中介绍过。
FontProperties
- 此属性类型为IPropertyStore
,包含所有字体相关的属性,例如Size
、Bold
、Underline
等。在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
辅助类将此属性公开为 .NETColor
,并内部处理与COLORREF
结构之间的转换。属性标识符:UI_PKEY_FontProperties_ForegroundColor
。ForegroundColorType
- 文本颜色类型。有效值是RGB
和Automatic
。如果选择了RGB
,用户应从ForegroundColor
属性获取颜色。如果选择了Automatic
,用户应使用SystemColors.WindowText
。FontControl
辅助类不公开ForegroundColorType
属性。相反,它在内部实现了颜色选择算法(即,根据类型属性返回正确的颜色)。属性标识符:UI_PKEY_FontProperties_ForegroundColorType
。BackgroundColor
- 当BackgroundColorType
设置为RGB
时包含背景颜色。FontControl
辅助类将此属性公开为 .NETColor
,并内部处理与COLORREF
结构之间的转换。属性标识符:UI_PKEY_FontProperties_BackgroundColor
。BackgroundColorType
- 背景颜色类型。有效值是RGB
和NoColor
。如果选择了RGB
,用户应从BackgroundColor
属性获取颜色。如果选择了NoColor
,用户应使用SystemColors.Window
。FontControl
辅助类不公开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
的实现,因此用户不再需要实现 Execute
和 UpdateProperty
方法。
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;
}
目前就到这里为止。