Windows Develop Bookmark and Share   
 index > Windows Forms General > Windows Forms General FAQ
 

Windows Forms General FAQ

This material should not be considered as a complete coverage of the frequently asked questions, but it tries to capture the high-level features with some depth in the Windows Forms General areas.

1. TREEVIEW

1.1 How to retain an expanded state after reloading TreeView?

1.2 How to show hierarchical data in TreeView?

1.3 How do I implement Drag and Drop support between two TreeViews?

1.4 How to hide CheckBoxes for child nodes when CheckBoxes is set to true.

2. TEXTBOX

2.1 How do I programmatically position the cursor on a given line and character in a RichTextBox?

2.2 How to save RTF-formatted data from a Windows Forms RTF control to SQL Server?

2.3 How to get the current character’s color of a RichTextBox?

2.4 How to make the scroll smoother in a RichTextBox?

2.5 If a rich text box contains images and text, is it possible to detect when an image is clicked?

2.6 How to make a TextBox only accept digits?

3. COMBOBOX

3.1 How do I setup a ComboBox to bind to a Lookup table?

3.2 How to add a ‘please select�item to ComboBox?

3.3 How to make the drop down part of the combo box wide enough to see all items?

4. LISTBOX

4.1 How to display tooltip on individual items in a ListBox?

4.2 How to add a business object to the item collection of a ListBox and display expected text?

4.3 How to do a dual Listbox?

5. MENUSTRIP

5.1 What’s the relationship between MainMenu and MenuStrip?

5.2 How do I disable the MenuStrip's ALT-key action?

5.3 How to set the count of items displayed in a MenuStripItem’s DropDown list?

6. TOOLSTRIP

6.1 How to set the height of ToolStrip and ToolStripItem?

6.2 How to make a ToolStripTextBox hide true text and replace them with '*'?

6.3 Why a ToolStripButton didn’t cause the validation?

7. TABPAGE

7.1 How to put a close button on TabPage header?

7.2 How to hide the header of TabPage?

Rong-Chun Zhang  Tuesday, December 04, 2007 12:31 PM

1.1 How to retain an expanded state after reloading TreeView?

That's going to be difficult. Other parent nodes might have been expanded. Capturing the entire state of the tree is tough. The need to refresh the entire tree is odd. You can just refresh the node contents of the existing tree. You could use the TreeNode.Tag property to retain some kind of reference to the source data.

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2203734&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 12:34 PM

1.2 How to show hierarchical data in TreeView?

First you should create all tree nodes using these records, and then you can use a hash table to store these tree nodes. Finally loop through the hash table and add these tree nodes hierarchically.

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1774847&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 12:43 PM

1.3 How do I implement Drag and Drop support between two TreeViews?

In a posting in the Microsoft.Windows.Forms newsgroup, Brian Roder (Microsoft) gives VB.Net code snippets to handle the DragEnter, ItemDrag and DragDrop events that provide a solution to this problem. Here are some sample handlers written in C#.

Code Block

private void treeView2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)

TreeNode newNode;

if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))

Point pt;

TreeNode destinationNode;

new Point(e.X, e.Y));

TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");

if (!destinationNode.Equals(newNode))

//destinationNode.Nodes.Add(newNode.Clone());

TreeNode)newNode.Clone());

//Remove original node

private void treeView2_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)

DragDropEffects.Move;

private void treeView2_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)

DragDropEffects.Move);

1.4 How to hide CheckBoxes for child nodes when CheckBoxes is set to true.

To enable this feature, we should owner draw the tree node. We can set the TreeView.DrawMode property to OwnerDrawAll and handle the DrawNode event. Try something like the following in this handler.

Code Block

private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)

if (IsThirdLevel(e.Node))

Color backColor, foreColor;

if ((e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected)

SystemColors.Highlight;

SystemColors.HighlightText;

else if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)

SystemColors.HotTrack;

SystemColors.HighlightText;

else

using (SolidBrush brush = new SolidBrush(backColor))

TextRenderer.DrawText(e.Graphics, e.Node.Text,
this.treeView.Font, e.Node.Bounds, foreColor, backColor);

if ((e.State & TreeNodeStates.Focused) == TreeNodeStates.Focused)

ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds,
foreColor, backColor);

false;

else

true;

private static bool IsThirdLevel(TreeNode node)

return node.Parent != null && node.Parent.Parent != null;

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1883238&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 12:52 PM

2.1 How do I programmatically position the cursor on a given line and character in a RichTextBox?

The RichTextBox control contains a Lines array property, one entry for every line. Each line entry has a Length property. With this information, you can position the selection cursor using code such as:

Code Block

private void GoToLineAndColumn(RichTextBox rtb, int line, int column)

if (line < 0 || column < 0)

else

if (line > rtb.Lines.Length - 1)

else

int firstCharIndexOfline = rtb.GetFirstCharIndexFromLine(line);

int textlengthOfline;

if (column > textlengthOfline)

2.2 How to save RTF-formatted data from a Windows Forms RTF control to SQL Server?

In this situation, using a RichTextBox is the easiest way; we can just bind the field to the Rtf property of RichTextBox.

Code BlockBinding bd =new Binding("Rtf", dt, "descs",true);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2246017&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 1:01 PM

2.3 How to get the current character’s color of a RichTextBox?

The RichTextBox has provided you a property named SelectionColor; you can use this property to get the current character’s color

private void richTextBox1_MouseMove(object sender, MouseEventArgs e)

int index = richTextBox1.GetCharIndexFromPosition(e.Location);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2139967&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 1:03 PM

2.4 How to make the scroll smoother in a RichTextBox?

Try to use two windows API functions, GetScrollPos and PostMessage. The GetScrollPos is used to get the current position of RichTextBox, and the PostMessage is used to place a scroll-down message in the message queue associated with the thread that created the window.

Code Block

"user32.dll", EntryPoint:="PostMessage")> _

Public Shared Function PostMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

End Function

"user32.dll", EntryPoint:="GetScrollPos")> _

Public Shared Function GetScrollPos(ByVal hwnd As Integer, ByVal nBar As Integer) As Integer

End Function

Public Const WM_VSCROLL As Integer = 277

Public Const SB_THUMBPOSITION As Integer = 4

Public Const SBS_VERT As Integer = 1

Private previousPos As Integer = 0

Private Sub RTBAutoScroll_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

Me.RichTextBox1.[Select](0, 0)

Me.RichTextBox1.ScrollToCaret()

Me.Timer1.Interval = 300

AddHandler Me.Timer1.Tick, AddressOf timer1_Tick

Dim td As New DateTime()

Me.Text = td.ToString()

End Sub

Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs)

Dim currentPos As Integer = GetScrollPos(CInt(Me.richTextBox1.Handle), SBS_VERT)

If previousPos <> currentPos OrElse currentPos = 0 Then

CInt(Me.richTextBox1.Handle), WM_VSCROLL, SB_THUMBPOSITION + 65536 * (currentPos + 1), 0)

End If

End Sub

Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If Button1.Text = "Auto Scroll" Then

"Pause"

True

ElseIf Button1.Text = "Pause" Then

"Auto Scroll"

False

End If

Sub

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2102412&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 1:06 PM

2.5 If a rich text box contains images and text, is it possible to detect when an image is clicked?

The Rich Text Format (RTF) Specification says, pictures are destinations, and begin with the \pict control word. We can try to judge the SelectedRtf string to see if this contains the \pict when click on the RichTextBox.

Code Block

this.richTextBox1.MouseClick += new MouseEventHandler(richTextBox1_MouseClick);

void richTextBox1_MouseClick(object sender, MouseEventArgs e)

if (this.richTextBox1.SelectedRtf.IndexOf(@"\pict") != -1 &&
this.richTextBox1.SelectionType == RichTextBoxSelectionTypes.Object)

MessageBox.Show("Image has been clicked!");

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2191267&SiteID=1

Rong-Chun Zhang  Tuesday, December 04, 2007 1:09 PM

2.6 How to make a TextBox only accept digits?

You can handle the textbox's KeyPress event and if the char passed in is not digits, mark the events argument as showing that the character has been handled. Below is a derived TextBox that only accepts digits (and control characters such as backspace).

Code Block

public class NumbersOnlyTextBox : TextBox

protected override void OnKeyPress(KeyPressEventArgs e)

base.OnKeyPress(e);

if (!(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)))

true;

3.1 How do I setup a ComboBox to bind to a Lookup table?

A common use of a ComboBox in a data bound application is as a lookup based UI control. From a database perspective, a Lookup control is used to provide the “lookup�values for a foreign key. For example, assume you have a customer table with a “StateID�where the “StateID�is a foreign key into a “States�table. From a UI perspective, you’d like to allow the user to select a State via a ComboBox. To do this, you use Complex Binding to bind the ComboBox to the States table (setting the ComboBox.DisplayMember and ComboBox.ValueMember) and use Simple List Binding to bind the ComboBox SelectedValue to the Customer “StateID�

Code Block

new Customer("Joe", "WA");

this.statesCB.DisplayMember = "Name";

this.statesCB.ValueMember = "Code";

this.statesCB.DataSource = statesTable;

this.statesCB.DataBindings.Add("SelectedValue", cust, "StateID", true);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1753655&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 1:48 PM

3.2 How to add a ‘please select�item to ComboBox?

If the ComboBox is not data bound, you can add an item to the item collection.

Code Block

this.comboBox1.Items.Insert(0, "please select");

this.comboBox1.SelectedIndex = 0;

If the ComboBox is data bound, you will need to add this item to the data source

Code Block

new Customer("Joe", null);

DataRow row = statesTable.NewRow();

"Name"] = " please select";

"Code"] = DBNull.Value;

this.statesCB.DisplayMember = "Name";

this.statesCB.ValueMember = "Code";

this.statesCB.DataSource = statesTable;

this.statesCB.DataBindings.Add("SelectedValue", cust, "StateID", true);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1769727&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 1:51 PM

3.3 How to make the drop down part of the combo box wide enough to see all items?

You can set the DropDownWidth of a combo box to make the combo box dropdown wide enough.

Code Block

string s = "this is a really, really, really, really, really, long string";

Graphics g = Graphics.FromHwnd(this.Handle);

SizeF size = g.MeasureString(s, comboBox1.Font);

Convert.ToInt32(size.Width);

.comboBox1.Items.Add(s);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2281333&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 1:54 PM

4.1 How to display tooltip on individual items in a ListBox?

If you want to display tooltip on individual items in a ListBox, here is a quick easy way. First create a method to handle mouse move events, and then hook it to the MouseMove event of the ListBox. You will also need a ToolTip object as a member variable for the form. The code required to create and update the tooltip is:

Code Block

private void onMouseMove(object sender, MouseEventArgs e)

if (sender is ListBox)

ListBox listBox = (ListBox)sender;

Point point = new Point(e.X, e.Y);

int hoverIndex = listBox.IndexFromPoint(point);

if (hoverIndex >= 0 && hoverIndex < listBox.Items.Count)

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2073944&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 1:56 PM

4.2 How to add a business object to the item collection of a ListBox and display expected text?

The most common way to achieve this is to set the DiaplayMember to the Proterty name of your business object.

The second way is to use a TypeConverter to convert the business object. You need to custom a TypeConverter and override its ConvertTo method. Check the following sample code.

Code Block

TypeConverter(typeof(BusinessTypeConvert))]

class BusinessObject

int id;

public int Id

get { return id; }

set { id = value; }

string name;

public string Name

get { return name; }

set { name = value; }

class BusinessTypeConvert :TypeConverter

public override object ConvertTo(ITypeDescriptorContext context,

CultureInfo culture, object value, Type destinationType)

if (destinationType == typeof(string))

return ((BusinessObject)value).Name;

return base.ConvertTo(context, culture, value, destinationType);

The third choice is to override the ToString method of your business object and return the expected text in this method. But this is not recommended since ToString method is usually used to return some information about the class.

Rong-Chun Zhang  Wednesday, December 05, 2007 1:59 PM

4.3 How to do a dual Listbox?

I want to use two buttons to move items back and forth. For example, ‘L->R�moves items from left ListBox to right ListBox, ‘R->L�moves items form right ListBox to left ListBox.

Place two ListBoxes with two buttons between them. One button with Text ‘R->L� and the other ‘L->R�

In the L->R click event handler:

Code Block

foreach (int index in listBox1.SelectedIndices)

In the R-L click event handler:

Code Block

foreach (int index in listBox2.SelectedIndices)

For both ListBoxes, the property SelectionMode should be set to MultiSimple. And place several items in one or both of the ListBoxes

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1830319&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 2:03 PM

5.1 What’s the relationship between MainMenu and MenuStrip?

MenuStrip is a complete replacement for MainMenu and has nothing in common with that control. The old MainMenu was built on top of the built-in Windows support for menus. The GetClientRect() API function automatically deducts the menu size from the client rectangle. MenuStrip doesn't use Windows menus, thus GetClientRect() returns the size of the window's client area, disregarding the space taken up by the MenuStrip. The same is true for any other window edge adornments like StatusStrip and ToolStrip, or any docked panels for that matter.

Rong-Chun Zhang  Wednesday, December 05, 2007 2:05 PM

5.2 How do I disable the MenuStrip's ALT-key action?

Just override the ProcessDialogKey in your form, as:

Code Block

protected override bool ProcessDialogKey(Keys keyData)

if ((keyData & Keys.Alt) == Keys.Alt)

return true;

else

return base.ProcessDialogKey(keyData);

5.3 How to set the count of items displayed in a MenuStripItem’s DropDown list?

If there are too many items in MenuStripItem’s item collection, it will use a lot of space to show these menus. I want to show only eight (or other number) menus. How can I achieve this?

We will need to set the AutoSize of the MenuStripItem’s DropDown portion to false and inputs its height.

Code Block

this.fileToolStripMenuItem.DropDown.AutoSize = false;

this.fileToolStripMenuItem.DropDown.Height = 200;

6.1 How to set the height of ToolStrip and ToolStripItem?

Try to set both ToolStrip and ToolStripItem’s AutoSize to false, and make sure your ToolStrip’s height is greater than all your ToolStripItems. Try something like the following:

Code Block

this.toolStrip1.AutoSize = false;

this.toolStripButton1.AutoSize = false;

this.toolStripButton2.AutoSize = false;

this.toolStripButton3.AutoSize = false;

this.toolStripButton1.Height = 20;

this.toolStripButton2.Height = 40;

this.toolStripButton3.Height = 60;

this.toolStrip1.Height = 65;

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2080536&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 2:10 PM

6.2 How to make a ToolStripTextBox hide true text and replace them with '*'?

The ToolStripTextBox actually contains a TextBox and use this TextBox to allow the user to type in. You can get the TextBox hosted in the ToolStripTextBox and set the PasswordChar property.

Code Block

if (this.toolStripTextBox1.Control is TextBox)

TextBox tb = this.toolStripTextBox1.Control as TextBox;

'*';

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2042939&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 2:12 PM

6.3 Why a ToolStripButton didn’t cause the validation?

By default, toolbars and menus do not need focus when you click on it, thus it does not force validation for controls. A related question is that why it didn’t commit the data to the database when clicking on a toolstrip. To solve this problem, add the following line of code in the click event to force the validation.

Code Block

this.Validate();//this refers to your form

Rong-Chun Zhang  Wednesday, December 05, 2007 2:14 PM

7.1 How to put a close button on TabPage header?

We can build a custom TabControl and override its OnDrawItem method in which you paint the "close button", then do the hit testing and close the tab when the "close button" is clicked. The following article demonstrates the idea in more detail:

http://www.codeproject.com/cs/miscctrl/firefoxtabcontrol.asp

Rong-Chun Zhang  Wednesday, December 05, 2007 2:15 PM

7.2 How to hide the header of TabPage?

Add a new class to your project, paste the code shown below and build the project. You can now drop the control from the top of the toolbox onto your form. At design time, the control looks like a regular TabControl. At run-time, you only see the pages. Use the SelectedIndex property to step through the pages.

Code Block

System;

System.Windows.Forms;

class WizardPages : TabControl

protected override void WndProc(ref Message m)

// Hide tabs by trapping the TCM_ADJUSTRECT message

if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;

else

base.WndProc(ref m);

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1518961&SiteID=1

Rong-Chun Zhang  Wednesday, December 05, 2007 2:17 PM

You can use google to search for other answers

Custom Search

More Threads

• Service security permission
• Menu Command Service
• Listbox and OutofMemoryException
• Tool bar using VB.net or C#
• Disappear of Shared folder
• invalid parameter used
• Simple Question; Racking Brain; headache... Using an Array to create product, price, quanity
• multicolumn checkedlistbox with vertical scrollbar
• DataGridView with row specific combo box contents
• add tabpages with datagridview to tab control