惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
量子位
有赞技术团队
有赞技术团队
博客园 - 三生石上(FineUI控件)
博客园 - Franky
M
MIT News - Artificial intelligence
U
Unit 42
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
J
Java Code Geeks
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
V
V2EX

博客园 - c#之旅

好久没有更新了,来露个头! GridView全选全不选以及读取隐藏列的值的方法 - c#之旅 - 博客园 使用css 控制GridView显示出来的数据 [转] 在asp.net 2.0中配置FCKeditor 2.6.4 ASP.NET 中使用Fckeditor 2.6.4 [幽默笑话]唐僧取经 表格细边框css 快过生日了,买了基本asp.net的书给自己做生日礼物 使用windows Live Writer来管理自己的博客 最近准备学习下asp.net ajax,朋友们多鼓励我啊! 好久没有更新了,不知道还有没有人关注?呵呵! 又是一年春来到,祝大家有个好的开始。 挺好看的小说《商业三国》 新年快到了,祝大家新年快乐! 这些天工作太忙了,一点时间都没有了 ASPxNewsControl 使用备忘 研究了一下午,终于找到了把框架中的立体分割线变成平面的方法了(去除三维效果) - c#之旅 - 博客园 细表格备忘 - c#之旅 - 博客园 css框架样式备忘(转)
使用 WebBrowser 控件作为 HTML 文本编辑器[转]
c#之旅 · 2009-04-16 · via 博客园 - c#之旅

C# (C# 2.0)
Windows, .NET (.NET 2.0)
Win32, VS (VS2005)
Dev
发表日期2006-9-12
更新日期2006-11-25

 

简介

刚才,我在编写一个聊天应用程序,其中一个聊天客户端是基于 web 的并以 ASP.NET 2.0 编写,另一个聊天客户端是 C# 编写的基于 Windows 窗体的 .NET 应用。对于此 Windows 窗体客户端,我需要一个可以输出 HTML 的富文本编辑器(a rich text editor) ,以便于 ASP.NET 的客户端可以显示 Windows 窗体客户端的聊天内容。这样,就排除了使用 RTF 文本框的可能。

我设计出的解决方案是在 Windows 窗体客户端,以编辑模式使用一个 WebBrowser 控件。对于 WebBrowser  控件中选定的文本,同时在 WebBrowser 控件的上方放置包含格式按钮的工具栏,以便设置文本格式。

本文说明了这个方案中,使用 WebBrowser 控件建立一个编辑器时的主要难点问题。因为源代码不难理解,我就不深入介绍了。 但是,我会介绍一些必要的实现技巧。

WebBrowser 控件设计模式设置

当使用此组件时,会自动应用设计模式,并为文档建立一个编辑模板。但是,作为参考,下面简单说明这是如何实现的。

应用设计模式需要使用 COM 接口,添加一个 MSHTML 的 "Microsoft HTML Object Library" 的引用,并添加一个对 'MSHTML' 的 'using'。

在把改变写入到 DOM 文档之前,有必要添加一个 body 到控件。要这样做,你可以简单地设置一些文本到 WebBrowser 控件的 DocumentText 属性中。

webBrowser1.DocumentText = "<html><body></body></html>"

下面的代码可以取得新的 DomDocument COM 接口的引用,并设置设计模式为 "On"。

IHTMLDocument2 doc =
webBrowser1.Document.DomDocument as IHTMLDocument2;
doc.designMode = "On";

最后,我把 WebBrowser 控件的上下文菜单替换掉,这样 IE 浏览器的默认上下文菜单就不会显示出来。

webBrowser1.Document.ContextMenuShowing += 
new HtmlElementEventHandler(Document_ContextMenuShowing);

浏览器现在处于设计模式中,使用一个自定义方法来显示指定的上下文菜单。

格式化文本

使用 browser.Document 中的 ExecCommand 方法,你可以把格式和编辑功能应用到设计模式下的浏览器控件。

下面是一些例子:

public void Cut()
{
webBrowser1.Document.ExecCommand("Cut", false, null);
}
public void Paste()
{
webBrowser1.Document.ExecCommand("Paste", false, null);
}
public void Copy()
{
webBrowser1.Document.ExecCommand("Copy", false, null);
}

某些命令用于绑定(显示)当前选区的格式。

public void Bold()
{
webBrowser1.Document.ExecCommand("Bold", false, null);
}

public void Italic()
{
webBrowser1.Document.ExecCommand("Italic", false, null);
}

同步刷新选定文本的格式按钮

下面介绍一些比发出格式化命令到浏览器更有用的技巧。每 200 毫秒,我逐一查询浏览器编辑选区的状态,并据此设置工具栏格式按钮的状态。

private void timer_Tick(object sender, EventArgs e)
{
SetupKeyListener();
boldButton.Checked = IsBold();
italicButton.Checked = IsItalic();
underlineButton.Checked = IsUnderline();
orderedListButton.Checked = IsOrderedList();
unorderedListButton.Checked = IsUnorderedList();
linkButton.Enabled = SelectionType == SelectionType.Text;

UpdateFontComboBox();
UpdateFontSizeComboBox();
if (Tick != null) Tick();
}

你可能已经注意到这儿使用了一个 Tick 计时器事件。外部的组件可以订阅此事件来更新 GUI 的状态。举例来说,它们将基于编辑器控件的状态,刷新“剪切/复制/粘贴/撤销/重复”(操作)的 Enabled 状态。

我通过使用WebBrowser 控件返回的 COM 文档接口,来完成此任务,先使用:

IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;

然后,使用 queryCommandState  方法来确定当前选区的状态:

public bool IsBold()
{
return doc.queryCommandState("Bold");
}

public bool IsItalic()
{
return doc.queryCommandState("Italic");
}

public bool IsUnderline()
{
return doc.queryCommandState("Underline");
}

连接按钮和字体控件以一种简单的方式管理,但我将会保留以代码检测的方法。

取得焦点

让控件取得焦点不一定是简单的。 WebBrowser 控件本身不接受焦点。 WebBrowser 控件的文档也不接受焦点。但是,body 会取得焦点,可以假定有一个 body 元素在控件中。

private void SuperFocus()
{
if (webBrowser1.Document != null &&
webBrowser1.Document.Body != null)
webBrowser1.Document.Body.Focus();
}

当然,你决不需要直接调用此方法。在控件上调用 Focus 方法,会把焦点放置到包含了 WebBrowser 控件的编辑器控件上。当接收到 GotFocus  事件时,编辑器控件会自动把焦点转到 WebBrowser 控件文档的 body 上。

取得文本或 HTML

分别使用 BodyHtmlBodyText 方法,可以返回 HTML 和文本。

连接到组件程序集

在 Visual Studio 2005 中,你可以连接到一个程序集 (添加一个引用),即使程序集是可执行的(文件)。此编辑器是作为内嵌在窗体的组件来编写的,因此你可以把这个组件添加到控件面板上,并把它拖放到你的应用程序中。此控件的名称为 Editor,在命名空间 Design 中。

结束语

.NET 2.0 中的 WebBrowser 控件可以作为一个有效的文本编辑器来使用。当你需要一个 HTML 编辑器控件时,它很有用。但是在某些范围内,不能完全直接地使用 WebBrowser 控件来实现。本文试图展示一些让它工作的必要技巧。