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

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (7投票s)

2008 年 10 月 15 日

CPOL

5分钟阅读

viewsIcon

48663

downloadIcon

1256

使用 WebBrowser 创建丰富、交互式用户控件

WebBrowserChatUserControlDemoRun.png

引言

当我想为我的应用程序创建一个聊天UserControl时,我遇到了一个问题,即我想在RichTextBox输出框中显示文本颜色。我开始在网上搜索,找到了各种方法(这个链接是一个不错的例子),但对我来说,那些方法似乎太复杂了,因为我不擅长 RTF,而且我也不喜欢太多的编码。在寻找真正解决方案的沮丧中,我看到了Visual StudioToolBox菜单中的WebBrowser控件,我想如果我能向其中添加HTML代码,它就能显示多么精彩的内容。像大多数沉迷于互联网的人一样,做过很多博客或论坛发帖,HTML编码对我来说不成问题。

本文档面向绝对新手;因此,在文章中,我最常用简单的非专业术语。我会尽量使其简短明了。

目录

  • 创建以WebBrowser作为输出显示的用户控件
  • 创建类属性
  • WebBrowser控件追加HTML代码
  • 事件处理
  • 可以节省您编写不必要长代码时间的技巧

创建用户控件

  1. 右键单击您的项目 -> 添加 -> 新建项…
  2. 在右侧面板中选择 Visual C# 项 -> Windows 窗体 -> 用户控件。我将其命名为HTMLChatControl
  3. 添加一个TableLayoutPanel(1 列 x 2 行)。设置Dock属性:Fill
  4. WebBrowser添加到顶部的单元格,将TextBox添加到底部的单元格。设置Dock属性:Fill

UserControl

提示:要使两个小的重叠按钮像图片中那样停留在控件窗体的右上方,请在添加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代码添加到您的浏览器中。每种方法与另一种相比都有其优点和缺点。

  1. 使用webBrowser.Document.Body.AppendChild(HtmlElement)HTML代码注入浏览器
  2. 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:首次发布
© . All rights reserved.