【Win 10应用开发】使用RichEditBox控件应注意的问题

Cle****-he UID.1073626
2016-01-26 发表

本帖最后由 Clever-he 于 2016-1-26 11:28 编辑

RichEditBox控件支持对多格式文本进行编辑,一般的文本输入控件可以使用TextBox,不过,如果希望编辑格式较为复杂的文本,就可以考虚使用RichEditBox控件。

RichEditBox控件中正在编辑的文本是由Document属性公开的,它是一个ITextDocument接口,该接口没有公开实现类型,只能通过RichEditBox类的Document属性来获取其实例,Win App的API类似于COM的形式出现,所以某些类型只公开了接口,而没有公开实现类型。

ITextDocument接口的Selection属性可以获取到当前编辑框中被选定的文本区域,如果编辑框中的文本没有被选定,那么该属性所获取的是当前光标所在的位置。ITextSelection接口从ITextRange接口中继承了许多成员,比较常用的有:

ParagraphFormat属性——设置段落格式。

CharacterFormat属性——设置某个文本区域的格式,如加粗显示等。

Copy方法、Cut方法、Paste方法——可以进行复制、剪切、粘贴操作。

MoveStart方法、MoveEnd方法、Move方法——移动文本插入点。

InsertImage方法——在文档中插入图像。

下面老周用一些例子来演示一下如何设置编辑文档的格式。

一、设置字体大小:

[mw_shl_code=csharp,true] // 设置选定文本的字体大小
editbox.Document.Selection.CharacterFormat.Size = (float)val;
[/mw_shl_code]

二、设置文本颜色:

[mw_shl_code=csharp,true]// 设置文本颜色
editbox.Document.Selection.CharacterFormat.ForegroundColor = c;
[/mw_shl_code]

三、在文档中插入图像:

[mw_shl_code=csharp,true] FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".jpeg");

StorageFile file = await picker.PickSingleFileAsync();
// 打开文件流
IRandomAccessStream stream = await file?.OpenReadAsync();
// 插入图片
editbox.Document.Selection.InsertImage(400, 300, 0, Windows.UI.Text.VerticalCharacterAlignment.Baseline, "图像", stream);
[/mw_shl_code]


四、对文本应用加粗显示:

[mw_shl_code=csharp,true]// FormatEffect.Toggle表示切换状态
editbox.Document.Selection.CharacterFormat.Bold = Windows.UI.Text.FormatEffect.Toggle;[/mw_shl_code]

设置为Toggle表示切换状态,即如果文本已处于加粗状态,就设置为正常字体;如果文本尚未加粗,就进行加粗处理。

五、为文本设置下划线:

[mw_shl_code=csharp,true] ITextCharacterFormat format = editbox.Document.Selection.CharacterFormat;
if (format.Underline == UnderlineType.Single )
{
format.Underline = UnderlineType.None;
}
else
{
format.Underline = UnderlineType.Single;
}


[/mw_shl_code]

从上面一堆例子也发现,其实RichEditBox用起来也不难,对号入座调用正确的成员就行。

但是,这个RichEditBox是一个问题控件,它有不少小问题。其中,比较突出的是:当为RichEditBox控件中选中的文本设置了字体颜色后,此时,把光标重新定位回RichEditBox控件,会发现字体又被恢复到原来的颜色,也就是说,我们对文本的颜色的修改无效。我相信这个问题不少人会遇到,在国外的一些技术社区也看到类似的提问。

造成这一问题的是元凶就是可视化状态,在RichEditBox的控件模板中声明了一个名为Focused的可视化状态,于是当控件获得焦点后会激活这个状态,并且把控件的前景色设置为默认的SystemControlForegroundChromeBlackHighBrush。

这是导致文本颜色设置后总是被还原的根源。

找到病因,就可以对症下药了。利用VS的XAML设计器为RichEditBox生成默认的控件模板,然后找到ControlTemplate里面根元素Grid下的VisualStateGroups组,接着找到CommonStates分组,你会看到里面有这么个可视化状态。

[mw_shl_code=csharp,true] <VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlPageTextChromeBlackMediumLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundChromeBlackHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="RequestedTheme" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="Light"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
[/mw_shl_code]


其中,有一个时间线对象会引起你的注意,就是它:

[mw_shl_code=csharp,true]<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundChromeBlackHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
[/mw_shl_code]

因为控件的Foreground属性的改变会影响编辑框中的文本,而当RichEditBox控件获得焦点时会激活Focused状态,这样的话,Foreground属性又被还原为默认值,从而把当前编辑文档的文本颜色也还原了。

所以,只要把这个ObjectAnimationUsingKeyFrames时间线去掉即可以解决问题,你如果不放心的话,可以先把它注释掉。


另外,RichEditBox还有一个问题,就是经常会发生无法将文本设置为斜体的情况,或者英文字母可以斜体,而中文字符不可用,又或者会出现加粗和斜体混在一起的问题。这个问题可能是字体的问题,老周暂时未找到解决方法。

最后,给大家看一下上面例子的执行效果。

***附件停止解析***

代码下载链接:***链接停止解析***

开发者交流群:53078485,期待您的加入!

标签: 开发

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
wcavell UID.34926
2016-01-26 使用 Lumia 920 回复

我只想知道如何输出html 而不是rtf

Showmaner5 UID.516232
2016-01-28 回复

支持 希望多出点技术方面的

Cle****-he UID.1073626
2016-01-28 回复

Quote***链接停止解析***
支持 希望多出点技术方面的


好的,谢谢支持

暗****手 UID.379158
2016-01-30 回复

转载要注明出处!

Leeway213 UID.76829
2016-02-02 使用 Lumia 830 回复

Quotewcavell 发表于 2016-1-26 12:50
我只想知道如何输出html 而不是rtf


同问!如何输出html
wpf时代有个rtf2html 不过是收费的 还不便宜

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报