Getting ComboBox to show a TreeView (Whidbey)
I tend to shy away from Whidbey only discussions here, but I've been asked a couple times how to get a combobox to show a treeview - so I thought I'd share with y'all what I whipped up in 20min. The interesting thing here is what you can do with a ToolStripDropDown and ToolStripControlHost. The ToolStripDropDown is a special kind of toplevel window (just like a form), and the ToolStripControlHost is a class that allows you to host arbitrary Controls within a ToolStrip/ToolStripDropDown.
As always, if you have problems with these classes, we're eager to get your feedback.
public Form1() {
InitializeComponent();
MyTreeViewCombo treeCombo = new MyTreeViewCombo();
// note: you may have to add these in Form.Load so the horizontal scrollbar doesnt appear
// See https://blogs.msdn.com/subhagpo/archive/2004/07/30/202665.aspx
treeCombo.TreeView.Nodes.Add("one");
treeCombo.TreeView.Nodes.Add("two");
treeCombo.TreeView.Nodes.Add("three");
this.Controls.Add(treeCombo);
}
public class MyTreeViewCombo : ComboBox {
ToolStripControlHost treeViewHost;
ToolStripDropDown dropDown;
public MyTreeViewCombo() {
TreeView treeView = new TreeView();
treeView.BorderStyle = BorderStyle.None;
treeViewHost = new ToolStripControlHost(treeView);
// create drop down and add it
dropDown = new ToolStripDropDown();
dropDown.Items.Add(treeViewHost);
}
public TreeView TreeView {
get { return treeViewHost.Control as TreeView; }
}
private void ShowDropDown() {
if (dropDown != null) {
treeViewHost.Width = DropDownWidth;
treeViewHost.Height = DropDownHeight;
dropDown.Show(this, 0, this.Height);
}
}
private const int WM_USER = 0x0400,
WM_REFLECT = WM_USER + 0x1C00,
WM_COMMAND = 0x0111,
CBN_DROPDOWN = 7;
public static int HIWORD(int n) {
return (n >> 16) & 0xffff;
}
protected override void WndProc(ref Message m) {
if (m.Msg == ( WM_REFLECT + WM_COMMAND)) {
if (HIWORD((int)m.WParam) == CBN_DROPDOWN) {
ShowDropDown();
return;
}
}
base.WndProc(ref m);
}
// Edit: 10:37, remember to dispose the dropdown as it's not in the control collection.
protected override void Dispose(bool disposing) {
if (disposing) {
if (dropDown != null) {
dropDown.Dispose();
dropDown = null;
}
}
base.Dispose(disposing);
}
}
}
Comments
- Anonymous
September 18, 2005
Orangy asks:
Hello, thanks for nice articles. Could you please write one about creating combobox-style... - Anonymous
September 18, 2005
Orangy asks:
Hello, thanks for nice articles. Could you please write one about creating combobox-style...