|
Hi, first of all i want to thank you for this nice control and i was wondering if its possible to populate the treeview from datatable or smth.
|
|
|
|
|
I want the user to only select from tree.He should not be allowed to type in(A functionality similar to ComboBoxStyle.DropDownList). How can i do this.
|
|
|
|
|
Hi there,
I did some fix to this great control.
I changed the BranchSeparator to String. Now we can use " :: " as BranchSeparator.
I also used a property called DropDownHeight to set the size of the dropdown box (treeview).
I did some work on the minimum Height and Width of the dropdownbox and fixed a 2 pixels paint problem. Now the ComboBox Button is shown as it should be.
I this thats it. Source on the reply.
|
|
|
|
|
using System;<br />
using System.ComponentModel;<br />
using System.Drawing;<br />
using System.Resources;<br />
using System.Text.RegularExpressions;<br />
using System.Windows.Forms;<br />
<br />
namespace Verlinea.ComboBoxTree {<br />
public delegate void NodeSelectEventHandler();<br />
public class ComboBoxTree : UserControl {<br />
#region Private Fields<br />
private Panel pnlBack;<br />
private Panel pnlTree;<br />
private TextBox tbSelectedValue;<br />
private ButtonEx btnSelect;<br />
private TreeView tvTreeView;<br />
private LabelEx lblSizingGrip;<br />
private Form frmTreeView;<br />
<br />
private string _branchSeparator;<br />
private bool _absoluteChildrenSelectableOnly;<br />
private int _dropDownHeight;<br />
private System.Drawing.Point DragOffset;<br />
#endregion<br />
#region Public Properties<br />
[Browsable(true), Description("Gets the TreeView Nodes collection"), Category("TreeView"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor(typeof(TreeNodeCollection), typeof(TreeNodeCollection))]<br />
public TreeNodeCollection Nodes {<br />
get {<br />
return this.tvTreeView.Nodes;<br />
}<br />
}<br />
<br />
[Browsable(true), Description("Gets or sets the TreeView's Selected Node"), Category("TreeView")]<br />
public TreeNode SelectedNode {<br />
set {<br />
this.tvTreeView.SelectedNode = value;<br />
}<br />
}<br />
<br />
[Browsable(true), Description("Gets or sets the TreeView's Selected Node"), Category("TreeView")]<br />
public ImageList Imagelist {<br />
get { return this.tvTreeView.ImageList; }<br />
set { this.tvTreeView.ImageList = value; }<br />
}<br />
<br />
[Browsable(true), Description("The text in the ComboBoxTree control"), Category("Appearance")]<br />
public override string Text {<br />
get { return this.tbSelectedValue.Text; }<br />
set { this.tbSelectedValue.Text = value; }<br />
}<br />
<br />
[Browsable(true), Description("Gets or sets the separator for the selected node's value"), Category("Appearance")]<br />
public string BranchSeparator {<br />
get { return this._branchSeparator; }<br />
set {<br />
if (value.Length > 0)<br />
this._branchSeparator = value;<br />
}<br />
}<br />
<br />
[Browsable(true), Description("Gets or sets the separator for the selected node's value"), Category("Behavior")]<br />
public bool AbsoluteChildrenSelectableOnly {<br />
get { return this._absoluteChildrenSelectableOnly; }<br />
set { this._absoluteChildrenSelectableOnly = value; }<br />
}<br />
<br />
[Browsable(true), Description("The heigth, in pixels, of the treeview in a combobox."), Category("Behavior")]<br />
public int DropDownHeight {<br />
get { return this._dropDownHeight; }<br />
set { this._dropDownHeight = value; }<br />
}<br />
#endregion<br />
<br />
public ComboBoxTree() {<br />
this.InitializeComponent();<br />
<br />
this.pnlBack = new Panel();<br />
this.pnlBack.BorderStyle = BorderStyle.Fixed3D;<br />
this.pnlBack.BackColor = Color.White;<br />
this.pnlBack.AutoScroll = false;<br />
<br />
this.tbSelectedValue = new TextBox();<br />
this.tbSelectedValue.BorderStyle = System.Windows.Forms.BorderStyle.None;<br />
<br />
this.btnSelect = new ButtonEx();<br />
this.btnSelect.Click += new EventHandler(ToggleTreeView);<br />
this.btnSelect.FlatStyle = FlatStyle.Flat;<br />
<br />
this.lblSizingGrip = new LabelEx();<br />
this.lblSizingGrip.Size = new Size(9, 9);<br />
this.lblSizingGrip.BackColor = Color.Transparent;<br />
this.lblSizingGrip.Cursor = Cursors.SizeNWSE;<br />
this.lblSizingGrip.MouseMove += new MouseEventHandler(SizingGripMouseMove);<br />
this.lblSizingGrip.MouseDown += new MouseEventHandler(SizingGripMouseDown);<br />
<br />
this.tvTreeView = new TreeView();<br />
this.tvTreeView.BorderStyle = BorderStyle.None;<br />
this.tvTreeView.DoubleClick += new EventHandler(TreeViewNodeSelect);<br />
this.tvTreeView.Location = new Point(0, 0);<br />
this.tvTreeView.LostFocus += new EventHandler(TreeViewLostFocus);<br />
<br />
this.frmTreeView = new Form();<br />
this.frmTreeView.FormBorderStyle = FormBorderStyle.None;<br />
this.frmTreeView.StartPosition = FormStartPosition.Manual;<br />
this.frmTreeView.ShowInTaskbar = false;<br />
this.frmTreeView.BackColor = System.Drawing.SystemColors.Control;<br />
<br />
this.pnlTree = new Panel();<br />
this.pnlTree.BorderStyle = BorderStyle.FixedSingle;<br />
this.pnlTree.BackColor = Color.White;<br />
<br />
SetStyle(ControlStyles.DoubleBuffer, true);<br />
SetStyle(ControlStyles.ResizeRedraw, true);<br />
<br />
this.pnlTree.Controls.Add(this.lblSizingGrip);<br />
this.pnlTree.Controls.Add(this.tvTreeView);<br />
this.frmTreeView.Controls.Add(this.pnlTree);<br />
this.pnlBack.Controls.AddRange(new Control[] { btnSelect, tbSelectedValue });<br />
this.Controls.Add(this.pnlBack);<br />
}<br />
<br />
private void RelocateGrip() {<br />
this.lblSizingGrip.Top = this.frmTreeView.Height - lblSizingGrip.Height - 1;<br />
this.lblSizingGrip.Left = this.frmTreeView.Width - lblSizingGrip.Width - 1;<br />
}<br />
<br />
private void ToggleTreeView(object sender, EventArgs e) {<br />
if (!this.frmTreeView.Visible) {<br />
Rectangle CBRect = this.RectangleToScreen(this.ClientRectangle);<br />
this.frmTreeView.Location = new System.Drawing.Point(CBRect.X, CBRect.Y + this.pnlBack.Height);<br />
<br />
this.frmTreeView.Show();<br />
this.frmTreeView.BringToFront();<br />
<br />
this.RelocateGrip();<br />
} else {<br />
this.frmTreeView.Hide();<br />
}<br />
}<br />
<br />
public bool ValidateText() {<br />
const char splitChar = '&';<br />
string ValidatorText = this.Text.Replace(this._branchSeparator, splitChar.ToString());<br />
TreeNodeCollection TNC = this.tvTreeView.Nodes;<br />
<br />
for (int i = 0; i < ValidatorText.Split(splitChar).Length; i++) {<br />
bool NodeFound = false;<br />
string NodeToFind = ValidatorText.Split(splitChar)[i];<br />
for (int j = 0; j < TNC.Count; j++) {<br />
if (TNC[j].Text == NodeToFind) {<br />
NodeFound = true;<br />
TNC = TNC[j].Nodes;<br />
break;<br />
}<br />
}<br />
<br />
if (!NodeFound)<br />
return false;<br />
}<br />
<br />
return true;<br />
}<br />
<br />
#region Events<br />
private void SizingGripMouseMove(object sender, MouseEventArgs e) {<br />
if (e.Button == MouseButtons.Left) {<br />
int TvWidth, TvHeight;<br />
TvWidth = Cursor.Position.X - this.frmTreeView.Location.X;<br />
TvWidth = TvWidth + this.DragOffset.X;<br />
TvHeight = Cursor.Position.Y - this.frmTreeView.Location.Y;<br />
TvHeight = TvHeight + this.DragOffset.Y;<br />
<br />
if (TvWidth < this.Width)<br />
TvWidth = this.Width;<br />
if (TvHeight < this._dropDownHeight)<br />
TvHeight = this._dropDownHeight;<br />
<br />
this.frmTreeView.Size = new System.Drawing.Size(TvWidth, TvHeight);<br />
this.pnlTree.Size = this.frmTreeView.Size;<br />
this.tvTreeView.Size = new System.Drawing.Size(this.frmTreeView.Size.Width - this.lblSizingGrip.Width, this.frmTreeView.Size.Height - this.lblSizingGrip.Width); ;<br />
RelocateGrip();<br />
}<br />
}<br />
<br />
private void SizingGripMouseDown(object sender, MouseEventArgs e) {<br />
if (e.Button == MouseButtons.Left) {<br />
int OffsetX = System.Math.Abs(Cursor.Position.X - this.frmTreeView.RectangleToScreen(this.frmTreeView.ClientRectangle).Right);<br />
int OffsetY = System.Math.Abs(Cursor.Position.Y - this.frmTreeView.RectangleToScreen(this.frmTreeView.ClientRectangle).Bottom);<br />
<br />
this.DragOffset = new Point(OffsetX, OffsetY);<br />
}<br />
}<br />
<br />
private void TreeViewLostFocus(object sender, EventArgs e) {<br />
if (!this.btnSelect.RectangleToScreen(this.btnSelect.ClientRectangle).Contains(Cursor.Position))<br />
this.frmTreeView.Hide();<br />
}<br />
<br />
private void TreeViewNodeSelect(object sender, EventArgs e) {<br />
if (this._absoluteChildrenSelectableOnly) {<br />
if (this.tvTreeView.SelectedNode.Nodes.Count == 0) {<br />
tbSelectedValue.Text = this.tvTreeView.SelectedNode.FullPath.Replace(@"\", this._branchSeparator);<br />
this.ToggleTreeView(sender, null);<br />
}<br />
} else {<br />
tbSelectedValue.Text = this.tvTreeView.SelectedNode.FullPath.Replace(@"\", this._branchSeparator);<br />
this.ToggleTreeView(sender, null);<br />
}<br />
}<br />
<br />
private void InitializeComponent() {<br />
this.Name = "ComboBoxTree";<br />
this._absoluteChildrenSelectableOnly = true;<br />
this._dropDownHeight = 106;<br />
this._branchSeparator = "-";<br />
this.Layout += new System.Windows.Forms.LayoutEventHandler(this.ComboBoxTree_Layout);<br />
}<br />
<br />
private void ComboBoxTree_Layout(object sender, System.Windows.Forms.LayoutEventArgs e) {<br />
this.Height = this.tbSelectedValue.Height + 10;<br />
this.pnlBack.Size = new Size(this.Width, this.Height - 2);<br />
<br />
this.btnSelect.Size = new Size(16, this.Height - 6);<br />
this.btnSelect.Location = new Point(this.Width - this.btnSelect.Width - 4, 0);<br />
<br />
this.tbSelectedValue.Location = new Point(2, 2);<br />
this.tbSelectedValue.Width = this.Width - this.btnSelect.Width - 4;<br />
<br />
this.tvTreeView.Height = this._dropDownHeight;<br />
this.frmTreeView.Size = new Size(this.Width, this.tvTreeView.Height);<br />
this.pnlTree.Size = this.frmTreeView.Size;<br />
this.tvTreeView.Width = this.frmTreeView.Width - this.lblSizingGrip.Width;<br />
this.tvTreeView.Height = this.frmTreeView.Height - this.lblSizingGrip.Width;<br />
this.RelocateGrip();<br />
}<br />
#endregion<br />
<br />
#region LabelEx<br />
private class LabelEx : Label {<br />
public LabelEx() {<br />
this.SetStyle(ControlStyles.UserPaint, true);<br />
this.SetStyle(ControlStyles.DoubleBuffer, true);<br />
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);<br />
}<br />
<br />
protected override void OnPaint(PaintEventArgs e) {<br />
base.OnPaint(e);<br />
System.Windows.Forms.ControlPaint.DrawSizeGrip(e.Graphics, System.Drawing.Color.Black, 1, 0, this.Size.Width, this.Size.Height);<br />
}<br />
}<br />
#endregion<br />
<br />
#region ButtonEx<br />
private class ButtonEx : Button {<br />
ButtonState state;<br />
<br />
public ButtonEx() {<br />
this.SetStyle(ControlStyles.UserPaint, true);<br />
this.SetStyle(ControlStyles.DoubleBuffer, true);<br />
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);<br />
<br />
}<br />
protected override void OnMouseDown(MouseEventArgs e) {<br />
state = ButtonState.Pushed;<br />
base.OnMouseDown(e);<br />
}<br />
<br />
protected override void OnMouseUp(MouseEventArgs e) {<br />
state = ButtonState.Normal;<br />
base.OnMouseUp(e);<br />
}<br />
<br />
protected override void OnPaint(PaintEventArgs e) {<br />
base.OnPaint(e);<br />
System.Windows.Forms.ControlPaint.DrawComboButton(e.Graphics, 0, 0, this.Width, this.Height, state);<br />
}<br />
}<br />
#endregion<br />
}<br />
}
|
|
|
|
|
Is there any way to set the FlatStyle to System so that it looks like a normal combobox in Windows XP with themes enabled?
Thanks,
Jake
|
|
|
|
|
Hi,
sure, just make some changed in ButtonEx:
1, replace
System.Windows.Forms.ControlPaint.DrawComboButton
with new special class
System.Windows.Forms.ComboBoxRenderer.DrawDropDownButton
2, and change
ButtonState state;
to
ComboBoxState state;
Br,
Ladislav Lencucha
|
|
|
|
|
First off, awesome work!!!
How can I consume AfterSelect event. I am not able to do that. What I want to do is execute a function when a node is selected.
Something like SelectedIndexChanged event of a dropdownlist.
Can you please help me whith this?
|
|
|
|
|
Never mind. Got it. Added an event AfterSelect to the source code.
|
|
|
|
|
If anyone is looking for it, heres how I did it.
Declare a delegate for AfterSelect event. This should come bofore the class definition starts:
public delegate void AfterSelectHandler(object sender, EventArgs e);
public class ComboBoxTree : UserControl
{
public event AfterSelectHandler AfterSelect;
protected virtual void OnAfterSelect(EventArgs e)
{
AfterSelect(this, e);
}
...
private void TreeViewLostFocus(object sender, EventArgs e)
{
//Excute the event handler on some event. I called /in TreeViewLostFocus
OnAfterSelect(e);
if (!this.btnSelect.RectangleToScreen (this.btnSelect.ClientRectangle).Contains(Cursor.Position))
this.frmTreeView.Hide();
}
}
|
|
|
|
|
Hi,
thanks for this control. I was jus looking for it.
I have the same problem as mayank_max10. I want to trigger an event that returns a node. I tried the code above but I don't understand some code.
1. Why do not use a TreeViewEventArgs over EventArgs e. EventArgs doesn't return a node.
the standard method used in treeView for Afterselect has TreeViewEventArgs as parm.
2. Why do I have to put a call to a OnAfterSelect(e) in TreeViewLostFocus? I want to call OnAfterSelect whan I select an Item , not when the control lost focus.
3. Could you help me to do this job the right way. I want to expand the nodes diynamically when the user click on a item that doesn't have children inside.
4. last question. if you decleare " protected virtual void OnAfterSelect" the keyword virtual does it means that the control overload the default method and than it is called when the user do what ???. Am I wrong ?
Thank for help.
Giorgio
|
|
|
|
|
I have added unsorted nodes in ComboboxTree, How should i sort the nodes of ComboboxTree?
|
|
|
|
|
Subject says it all. I can't C# my way out of a wet paper bag with a hole in it.
Thanks!
Please respond to mikesyd<at>cybermike<dot><net>
-- modified at 10:19 Tuesday 28th November, 2006
ok.. I bit the bullet and leaped into the C# code. I added properties to set the size of the treeview control at design time. I'd be happy to upload my work somewhere - but where.
In conclusion, I will say that this is a very nice piece of code because of the way it is packaged (a .DLL file) making it easily portable. I would love to have the technology to add the Intellisense info for properties and methods, but don't know how to do that. The one thing I dislike about this is that it gives focus to a hidden form, and your application window loses focus as a result. It would be just as well for those inclined to do some fancy UI coding to put the controls and events directly into your application form. What is being done here is simple UI and event manipulation of existing controls.
|
|
|
|
|
Hi,
I have found a bug in comboboxtree.cs file line 66 (if(value.Length > 0)) . Sometimes "value" is null. Modify the code and try this: if(value != null && value.Length > 0)
Thats all
Operator
-- modified at 7:45 Tuesday 3rd January, 2006
|
|
|
|
|
when dropdown ,the from lost focus, I do not want to be like this...
|
|
|
|
|
Wang, the only way to allow drawing the treeview outside the bounds of the form is to use its own form. I don't think two forms can be focused at one time so I don't think this is possible.
|
|
|
|
|
Very nice work, and I look forward to its evolution.
Thanks !
best, Bill Woodruff
dotScience
Chiang Mai, Thailand
"The greater the social and cultural distances between people, the more magical the light that can spring from their contact." Milan Kundera in Testaments Trahis
|
|
|
|
|
Hi!
I saw a small button on your Windows title bar. I'm interrested to use one like it. Do you have stuff or tricks to put a button there ? Thanks
|
|
|
|
|
It's part of the nView desktop manager available on nVidia graphics cards. I'm not sure how they put it there (it's probably not very documented, as I think that it violates Microsoft's UI design guidelines), if you're asking about putting one up yourself. The nView stuff allows you to make windows always-on-top, transparent, etc.
|
|
|
|
|
|
This is link to article published on this site long time ago, in it you can find solution to some aspects of combos with TreeView controls.
I think this can help us to make both my and yours controls better.
http://www.codeproject.com/cs/miscctrl/customcombos.asp[^]
Good Luck
Alex Kucherenko
|
|
|
|
|
Nice controls Alex. I've always intended on giving the control the option of the "flat appearance" and would love to be able show the selected item's image as well. I'll take a look at your code a bit further when I get the time
Gabe
|
|
|
|
|
It looks like you have to choose a node that has no child nodes (ie end node)... in which case it might be an idea to expand all nodes?
|
|
|
|
|
Thanks for the kind words Ashley. Based on your suggestion and a few of my own thoughts I'll be adding the following code to the control this weekend:
* attempt to expose more/all of the standard treeview methods/properties/events (ie. ExpandAll())
* implement public property bool AbsoluteChildrenSelectableOnly
* implement a NodeText validation algorithm to validate typed values
Best regards,
Gabe (obsidience)
|
|
|
|
|