-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdropdown_treeview.cs
More file actions
224 lines (200 loc) · 8.83 KB
/
dropdown_treeview.cs
File metadata and controls
224 lines (200 loc) · 8.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.Serialization;
// http://www.codeproject.com/Articles/14544/A-TreeView-Control-with-ComboBox-Dropdown-Nodes
namespace DropDownTreeView
{
public class DropDownTreeNode : TreeNode
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
public DropDownTreeNode()
: base()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
/// <param name="text">The text.</param>
public DropDownTreeNode(string text)
: base(text)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="children">The children.</param>
public DropDownTreeNode(string text, TreeNode[] children)
: base(text, children)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
/// <param name="serializationInfo">A <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> containing the data to deserialize the class.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"></see> containing the source and destination of the serialized stream.</param>
public DropDownTreeNode(SerializationInfo serializationInfo, StreamingContext context)
: base(serializationInfo, context)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <param name="selectedImageIndex">Index of the selected image.</param>
public DropDownTreeNode(string text, int imageIndex, int selectedImageIndex)
: base(text, imageIndex, selectedImageIndex)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeNode"/> class.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <param name="selectedImageIndex">Index of the selected image.</param>
/// <param name="children">The children.</param>
public DropDownTreeNode(string text, int imageIndex, int selectedImageIndex, TreeNode[] children)
: base(text, imageIndex, selectedImageIndex, children)
{
}
#endregion
#region Property - ComboBox
private ComboBox m_ComboBox = new ComboBox();
/// <summary>
/// Gets or sets the ComboBox. Lets you access all of the properties of the internal ComboBox.
/// </summary>
/// <example>
/// For example,
/// <code>
/// DropDownTreeNode node1 = new DropDownTreeNode("Some text");
/// node1.ComboBox.Items.Add("Some text");
/// node1.ComboBox.Items.Add("Some more text");
/// node1.IsDropDown = true;
/// </code>
/// </example>
/// <value>The combo box.</value>
public ComboBox ComboBox
{
get
{
this.m_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
return this.m_ComboBox;
}
set
{
this.m_ComboBox = value;
this.m_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
}
}
#endregion
}
/// <summary>
/// Provides the usual TreeView control with the ability to edit the labels of the nodes
/// by using a drop-down ComboBox.
/// </summary>
public class DropDownTreeView : TreeView
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="T:DropDownTreeView"/> class.
/// </summary>
public DropDownTreeView()
: base()
{
}
#endregion
// We'll use this variable to keep track of the current node that is being edited.
// This is set to something (non-null) only if the node's ComboBox is being displayed.
private DropDownTreeNode m_CurrentNode = null;
/// <summary>
/// Occurs when the <see cref="E:System.Windows.Forms.TreeView.NodeMouseClick"></see> event is fired
/// -- that is, when a node in the tree view is clicked.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.TreeNodeMouseClickEventArgs"></see> that contains the event data.</param>
protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
{
// Are we dealing with a dropdown node?
if (e.Node is DropDownTreeNode)
{
this.m_CurrentNode = (DropDownTreeNode)e.Node;
// Need to add the node's ComboBox to the TreeView's list of controls for it to work
this.Controls.Add(this.m_CurrentNode.ComboBox);
// Set the bounds of the ComboBox, with a little adjustment to make it look right
this.m_CurrentNode.ComboBox.SetBounds(
this.m_CurrentNode.Bounds.X - 1,
this.m_CurrentNode.Bounds.Y - 2,
this.m_CurrentNode.Bounds.Width + 25,
this.m_CurrentNode.Bounds.Height);
// Listen to the SelectedValueChanged event of the node's ComboBox
this.m_CurrentNode.ComboBox.SelectedValueChanged += new EventHandler(ComboBox_SelectedValueChanged);
this.m_CurrentNode.ComboBox.DropDownClosed += new EventHandler(ComboBox_DropDownClosed);
// Now show the ComboBox
this.m_CurrentNode.ComboBox.Show();
this.m_CurrentNode.ComboBox.DroppedDown = true;
}
base.OnNodeMouseClick(e);
}
/// <summary>
/// Handles the SelectedValueChanged event of the ComboBox control.
/// Hides the ComboBox if an item has been selected in it.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
void ComboBox_SelectedValueChanged(object sender, EventArgs e)
{
HideComboBox();
}
/// <summary>
/// Handles the DropDownClosed event of the ComboBox control.
/// Hides the ComboBox if the user clicks anywhere else on the TreeView or adjusts the scrollbars, or scrolls the mouse wheel.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
void ComboBox_DropDownClosed(object sender, EventArgs e)
{
HideComboBox();
MessageBox.Show(this.SelectedNode.Text.ToString());
}
/// <summary>
/// Handles the <see cref="E:System.Windows.Forms.Control.MouseWheel"></see> event.
/// Hides the ComboBox if the user scrolls the mouse wheel.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
protected override void OnMouseWheel(MouseEventArgs e)
{
HideComboBox();
base.OnMouseWheel(e);
}
/// <summary>
/// Method to hide the currently-selected node's ComboBox
/// </summary>
private void HideComboBox()
{
if (this.m_CurrentNode != null)
{
// Unregister the event listener
this.m_CurrentNode.ComboBox.SelectedValueChanged -= ComboBox_SelectedValueChanged;
this.m_CurrentNode.ComboBox.DropDownClosed -= ComboBox_DropDownClosed;
// Copy the selected text from the ComboBox to the TreeNode
this.m_CurrentNode.Text = this.m_CurrentNode.ComboBox.Text;
// Hide the ComboBox
this.m_CurrentNode.ComboBox.Hide();
this.m_CurrentNode.ComboBox.DroppedDown = false;
// Remove the control from the TreeView's list of currently-displayed controls
this.Controls.Remove(this.m_CurrentNode.ComboBox);
// And return to the default state (no ComboBox displayed)
this.m_CurrentNode = null;
}
}
}
}