使用 WebBrowser 控件作为显示引擎的聊天用户控件






3.71/5 (7投票s)
使用 WebBrowser 创建丰富、交互式用户控件

引言
当我想为我的应用程序创建一个聊天UserControl
时,我遇到了一个问题,即我想在RichTextBox
输出框中显示文本颜色。我开始在网上搜索,找到了各种方法(这个链接是一个不错的例子),但对我来说,那些方法似乎太复杂了,因为我不擅长 RTF,而且我也不喜欢太多的编码。在寻找真正解决方案的沮丧中,我看到了Visual Studio的ToolBox
菜单中的WebBrowser
控件,我想如果我能向其中添加HTML代码,它就能显示多么精彩的内容。像大多数沉迷于互联网的人一样,做过很多博客或论坛发帖,HTML编码对我来说不成问题。
本文档面向绝对新手;因此,在文章中,我最常用简单的非专业术语。我会尽量使其简短明了。
目录
- 创建以
WebBrowser
作为输出显示的用户控件 - 创建类属性
- 向
WebBrowser
控件追加HTML代码 - 事件处理
- 可以节省您编写不必要长代码时间的技巧
创建用户控件
- 右键单击您的项目 -> 添加 -> 新建项…
- 在右侧面板中选择 Visual C# 项 -> Windows 窗体 -> 用户控件。我将其命名为
HTMLChatControl
- 添加一个
TableLayoutPanel
(1 列 x 2 行)。设置Dock
属性:Fill
- 将
WebBrowser
添加到顶部的单元格,将TextBox
添加到底部的单元格。设置Dock
属性:Fill
提示:要使两个小的重叠按钮像图片中那样停留在控件窗体的右上方,请在添加WebBrowser
之前,先将一个Panel添加到顶部的单元格。还要确保将按钮的Anchor
属性设置为 Top|Right。如果您添加了按钮,您也可以添加一个 Font 或 Color 对话框控件,并将按钮点击事件连接到 Font | Color ShowDialog
。
为用户控件创建属性
在我的应用程序中,这两个按钮用于设置背景颜色和文本颜色。
public string Text
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
public Color ColorBackGround
{
get { return button_BackGroundColor.BackColor; }
set { button_BackGroundColor.BackColor = value; }
}
public Color ColorText
{
get { return button_TextColor.BackColor; }
set { button_TextColor.BackColor = value; }
}
注意:我使用子控件的属性值来存储宿主用户控件的属性值。
追加 HTML 代码
我认为有两种方法可以在运行时将HTML代码添加到您的浏览器中。每种方法与另一种相比都有其优点和缺点。
- 使用
webBrowser.Document.Body.AppendChild(HtmlElement)
将HTML代码注入浏览器 - 将HTML页面存储在
string
变量中,然后webBrowser.DocumentText = [the string]
。此方法的主要问题是如何在运行时操作HTML字符串。我认为这并不难,因为 HTML 只是XML的扩展,并且我们在 .NET Framework 中有一个内置的 XML 程序集。我首先想到了这个方法,但还没有尝试它是否可行。
在本文中,我将使用第一种方法将HTML代码追加到WebBrowser
控件。
public void AppendText(string mgs, Color c)
{
//create a tag
HtmlElement htmlSPAN = webBrowser1.Document.CreateElement("SPAN");
HtmlElement htmlFont = webBrowser1.Document.CreateElement("FONT");
//Set Attribute: color="rgb{#,#,#)"
htmlFont.SetAttribute("color", string.Format
("rgb({0},{1},{2})", c.R, c.G, c.B));
//insert text between tags
htmlFont.InnerText = mgs;
//Append a tag to another tag
htmlSPAN.AppendChild(htmlFont);
//same thing here but this time to the webbrowser
webBrowser1.Document.Body.AppendChild(htmlSPAN);
}
注意:Document.CreateElement("[tag]")
方法实际上并没有将元素添加到浏览器文档中。
注意:创建FONT
标签不是必需的。您可以使用以下方法直接设置color
[HtmlElement].Style = string.Format
("background-color:rgb({0},{1},{2});", c.R, c.G, c.B);
您不能为style
设置属性。例如:
SetAttribute(“style”, [string value])
它会编译,但不会做任何事情。
添加带点击事件的链接文本也是如此
public void AppendLinkText(string mgs, string href, Color c)
{
//create a HTML tag
HtmlElement htmlA = webBrowser1.Document.CreateElement("A");
HtmlElement htmlFont = webBrowser1.Document.CreateElement("FONT");
//Set Attribute: href=[string value]
htmlA.SetAttribute("href", href);
//register click event [See Event Handling]
htmlA.Click += new HtmlElementEventHandler(htmlItem_Click);
//Set Attribute: color="rgb{#,#,#)"
htmlFont.SetAttribute("color", string.Format("rgb({0},{1},{2})", c.R, c.G, c.B));
//insert text between tag
htmlFont.InnerText = mgs;
//Append a tag to another tag
htmlA.AppendChild(htmlFont);
//Append to the document
webBrowser1.Document.Body.AppendChild(htmlA);
}
并添加新行…
public void AppendNewLine()
{
HtmlElement htmlBR = webBrowser1.Document.CreateElement("BR");
webBrowser1.Document.Body.AppendChild(htmlBR);
}
更改背景颜色
public void SetBackgroundColor(Color c)
{
//webBrowser1.Document.Body.Style =
//string.Format("background-color:rgb({0},{1},{2});", c.R, c.G, c.B);
webBrowser1.Document.Body.SetAttribute
("bgcolor", string.Format("rgb({0},{1},{2})", c.R, c.G, c.B));
button_BackGroundColor.BackColor = c;
}
提示:如果您现在尝试构建应用程序,它将毫无错误地编译。但是,如果您尝试测试任何Append
函数,您将收到空引用运行时错误。原因是webBrowser1.Document
中没有任何内容!!!我不会在这篇文章中展示克服此问题的技巧。我认为您可以自己发现(到目前为止我能想到 2 种方法)。如果您放弃了,请查看我的源代码。
事件处理
记住我们在上面的AppendLinkText()
中有点击事件;您希望点击事件做什么?对于我的演示应用程序,它将触发一个自定义事件,让宿主窗口处理操作。我将我的自定义事件命名为WebItemClick
。我还将需要一个自定义事件处理程序来处理我的事件。
public event WebItemClickEventHandler WebItemClick;
事件处理程序还需要一个自定义事件参数来传递值。
注意:我将以下代码放在HTMLChatControl : UserControl
类括号之外
public class WebItemClickEventArgs : EventArgs
{
private string _itemValue;
public string ItemValue
{ get { return _itemValue; } set { _itemValue = value; } }
}
public delegate void WebItemClickEventHandler
(object sender, WebItemClickEventArgs e);
注意:按照惯例,您会将此代码放在UserControl
类之前。但是,当您尝试编译应用程序时,您很快就会意识到您应该将此代码放在底部。为什么?为什么不自己测试一下。
现在您所要做的就是将htmlItem_Click()
方法添加到您的聊天控件类中。
private void htmlItem_Click(object sender, HtmlElementEventArgs e)
{
//cast the sender object to HtmlElement (the sender is the A tag)
HtmlElement htmle = sender as HtmlElement;
//create new WebItemClickEventArgs
WebItemClickEventArgs eg = new WebItemClickEventArgs();
//get the attribute of the tag and assign it to EventArgs value
eg.ItemValue = htmle.GetAttribute("href");
//fire the event
WebItemClick(this, eg);
}
我再次总结一下我一直在努力实现的目标。当我点击WebBrowser
上的链接文本时,它将调用htmlItem_Click()
,然后该方法将触发WebItemClick
事件。我的宿主 Windows 窗体现在通过注册WebItemClick
事件,可以获取被点击项的值。
可以节省您编写不必要长代码时间的技巧
您可能会在某个时候遇到这些问题。
-
如何在文本框中输入时捕获回车键?
private void HtmlChatControl1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { //Do works } } //or private void HtmlChatControl1_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)13) { //do works } }
-
我在我的聊天控件上尝试了上面的代码,但它仍然不起作用。
//Reason: Key events including KeyDown, KeyUp, KeyPress event //would not work on the host windows // because the textbox's Key Events in your user control takes over them. //Here is the solution. //Put it in the control contains the text box. //Also don't forget to register the event //eg: textBox1.KeyDown += KeyEventHadler(textBox1_KeyDown); private void textBox1_KeyDown(object sender, KeyEventArgs e) { this.OnKeyDown(e); }
-
我禁用了
WebBrowser
的默认右键菜单(IsWebBrowserContextMenuEnabled = false
),并添加了自定义的ContextMenuStrip
(因为默认右键菜单包含不需要的命令)。如何保留复制高亮文本的功能?//You can do so with the Paste command! webBrowser1.Document.ExecCommand("Copy", false, null);
结论
WebBrowser
控件是一个非常强大的显示引擎,可以显示图像、表格等,甚至支持JavaScript。使用WebBrowser
控件,您可以为您的应用程序带来更丰富、更具交互性的元素。
关于我
我只是一个新手,与 Code Project 的大多数老兵相比,我是一个非常初级的程序员。我几年前才开始学习编程,仍然是一个非常有经验的编码员。我不是软件开发人员或类似的人。我是一名计算机硬件技术人员,换句话说,就是计算机维修员。我只在繁忙的学生生涯的业余时间编写代码以供娱乐。
我明白知识就是力量,我感谢那些花费宝贵时间撰写文章与他人分享他们力量的人。我正在努力成为他们中的一员。
请评价我的帖子并留下您的建设性意见。
历史
- 2008/10/10:首次发布