Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Chat User Control with WebBrowser Control as Displaying Engine

3.71/5 (7 votes)
15 Oct 2008CPOL5 min read 1   1.2K  
Create rich, interactive user control using WebBrowser
WebBrowserChatUserControlDemoRun.png

Introduction

When I was trying to create a chat UserControl for my apps, I ran into the problem where I wanted to display text color in the RichTextBox output box. I began Googling around and found a variety of ways (this link is one of the good ones), but those seemed to be too complicated to me because I'm not good at RTF and I don't like too much coding. In the frustration of looking for a real solution, I saw the WebBrowser control in the ToolBox menu of Visual Studio, and I thought of wonderful things a browser could display if I can add HTML code to it. Like most Internet addicted people who have done a lot of blogging or forum posting, HTML coding would not be a problem to me.

This article is intended for absolute beginners; therefore most often in the article, I use simple un-professional terms. I will try to make it short and clear.

Contents

  • Creating User Control with WebBrowser as output display
  • Create Class property
  • Append HTML code to WebBrowser control
  • Events Handling
  • Tips that can save you time from writing unnecessary long code

Creating User Control

  1. Right click on your Project -> Add -> New Item…
  2. Select Visual C# Item -> Windows Forms -> User Control on the right panel. I name it HTMLChatControl
  3. Add a TableLayoutPanel (1 col X 2 rows). Set Dock Property: Fill
  4. Add a WebBrowser to the top cell and TextBox to the bottom cell. Set Dock Property: Fill

UserControl

Tips: To have the two small overlaying buttons staying on the top right corner of the control form as you see in the picture, add a Panel to the top cell, before adding the WebBrowser. Also make sure to set the Buttons' Anchor property to Top|Right. If you add the buttons, you could also add a Font or a Color Dialog control and wire the button click event to the Font | Color ShowDialog.

Create Properties for the User Control

In my apps, the two buttons are for setting the background color and text color.

C#
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; }
}

Note: I use the child controls' property values to store the host User Control property values.

Appending HTML Code

There are two ways I can think of for adding HTML code to your browser at runtime. Each way has some benefits and disadvantages compared to the other.

  1. Inject the HTML code to the browser using webBrowser.Document.Body.AppendChild(HtmlElement)
  2. Store the HTML page in a string variable and then webBrowser.DocumentText = [the string]. The main problem with this method is how to manipulate the HTML string at runtime. I think it would not be so hard seeing that HTML is just an extension of XML and we have a built-in XML assembly available in .NET Frameworks. I thought of this method first, but have not tried if it would work.

I'm using the first method for this article to append the HTML code to the WebBrowser control.

C#
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);
}

Note: The Document.CreateElement("[tag]") method does not actually add the element to the browser document.

Note: It's not necessary to create a FONT tag. You can just set the color using:

C#
[HtmlElement].Style = string.Format 
	("background-color:rgb({0},{1},{2});", c.R, c.G, c.B); 

You CANNOT set an attribute for style. e.g.:

C#
SetAttribute("style", [string value])

It will compile but it won't do anything.

The same thing for adding linked text with a click event:

C#
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);
}

And adding a new line...

C#
public void AppendNewLine()
{
    HtmlElement htmlBR = webBrowser1.Document.CreateElement("BR");
    webBrowser1.Document.Body.AppendChild(htmlBR);
}

Change the background color:

C#
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;
}

Tips: If you try to build the app right now, it will compile without any error. However, if you try to test any of the Append functions, you will get null reference runtime error. The reason is there is nothing in the webBrowser1.Document!!! I will not show the trick to overcome this issue in this article. I think you can discover that yourself (I could think of 2 ways so far). If you give up, look at my source code.

Event Handling

Remember we have a click event in the AppendLinkText() above; What do you want the click events to do? For my demo app, it will fire up a custom event and let the host windows take care of the actions. I named my custom event WebItemClick. I will also need a custom event handler for my event.

C#
public event WebItemClickEventHandler WebItemClick;

The Event handler also needs a custom event argument to pass the value on.

Note: I put the following code outside of the HTMLChatControl : UserControl class bracket:

C#
public class WebItemClickEventArgs : EventArgs
{
    private string _itemValue;
    public string ItemValue 
    	{ get { return _itemValue; } set { _itemValue = value; } }
}

	public delegate void WebItemClickEventHandler
			(object sender, WebItemClickEventArgs e);	

Note: Conventionally, you would put this code before the UserControl class. However you will soon realize you should put this code at the bottom before you try to compile the app. Why??? Why don't you test that yourself.

Now all you have to do is to add the htmlItem_Click() method to your chat control class.

C#
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);
}

Again let me summarize what I have been trying to accomplish. When I click on the link text on the WebBrowser, it will call htmlItem_Click() which will in turn fire the WebItemClick event. My host Windows Form now, by registering the WebItemClick event, can get the clicked item's value.

Tips That Can Save You Time from Writing Unnecessary Long Code

You might run into these problems at some point.

  • How can I catch the Enter Key when typing on the text box?

    C#
    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
        }
    }
  • I try the above code on my chat control, but it is still not working.

    C#
    //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);
    }
  • I disable  the default right click menu of the WebBrowser (IsWebBrowserContextMenuEnabled = false)  and add my custom ContextMenuStrip (because the default right click menu has unwanted commands). How can I keep the copy highlighted text function?

    Go here to learn more.

    C#
    //You can do so with the Paste command!
    webBrowser1.Document.ExecCommand("Copy", false, null);

Conclusion

WebBrowser control is a very powerful display engine that can show images, tables, etc., and can even support JavaScript. Using the WebBrowser control, you can bring richer, more interactive elements to your application.

About Me

I'm just a newbie, a very beginner programmer compared to most veterans here on the Code Project. I just began learning about programming a few years ago and I'm still a very inexperienced coder. I'm not a software developer or anything like that. I'm working as a computer hardware technician or a computer repair guy in other words. I only write code for fun during spare times of my busy college student's life.

I understand that knowledge is power, and I appreciate those who spend their precious time writing articles sharing their power with others. I trying to be like one of them.

Please rate my post and leave your constructive comments.

History

  • 10/10/2008: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)