1 //------------------------------------------------------------------------------
2 // <copyright file="EditableTreeList.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 namespace System.Web.UI.Design.MobileControls.Util
8 {
9     using System;
10     using System.Diagnostics;
11     using System.Drawing;
12     using System.ComponentModel;
13     using System.Globalization;
14     using System.Windows.Forms;
15     using System.Web.UI.Design.MobileControls;
16 
17     [
18         ToolboxItem(false),
19         System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
20             Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
21     ]
22     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
23     internal class EditableTreeList : Panel
24     {
25 
26         private const String _assertMsgNullNodeSelected =
27             "Caller is responsible for ensuring a TreeNode is selected. "
28             + "Modified TreeViewNode without calling UpdateButtonsEnabling()?";
29 
30         private const String _assertMsgOutOfBounds =
31             "Caller is responsible for ensuring this action does not move the "
32             + "selected TreeViewNode out of bounds. "
33             + "Modified TvList without calling UpdateButtonsEnabling()?";
34 
35         internal TreeNode LastNodeChanged = null;
36         internal TreeNode EditCandidateNode = null;
37         internal EventHandler RemoveHandler;
38         private bool _caseSensitive;
39 
40         internal System.Windows.Forms.Button BtnAdd;
41         internal System.Windows.Forms.Button BtnRemove;
42         internal System.Windows.Forms.Button BtnDown;
43         internal System.Windows.Forms.Button BtnUp;
44         internal System.Windows.Forms.TreeView TvList;
45         internal System.Windows.Forms.Label LblTitle;
46         internal System.Windows.Forms.ContextMenu CntxtMenu;
47         internal System.Windows.Forms.MenuItem CntxtMenuItem;
48 
EditableTreeList()49         internal EditableTreeList() : this(true, true, 16)
50         {
51         }
52 
EditableTreeList(bool showAddButton, bool caseSensitive, int Y)53         internal EditableTreeList(bool showAddButton, bool caseSensitive, int Y)
54         {
55             this.TvList = new System.Windows.Forms.TreeView();
56             this.BtnAdd = new System.Windows.Forms.Button();
57             this.BtnDown = new System.Windows.Forms.Button();
58             this.LblTitle = new System.Windows.Forms.Label();
59             this.BtnUp = new System.Windows.Forms.Button();
60             this.BtnRemove = new System.Windows.Forms.Button();
61             this.CntxtMenuItem = new System.Windows.Forms.MenuItem();
62             this.CntxtMenu = new System.Windows.Forms.ContextMenu();
63 
64             LblTitle.Size = new System.Drawing.Size(210, 16);
65             LblTitle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;;
66 
67             TvList.Location = new System.Drawing.Point(0, 16);
68             TvList.Size = new System.Drawing.Size(178, 148);
69             TvList.ForeColor = System.Drawing.SystemColors.WindowText;
70             TvList.Anchor = AnchorStyles.Top
71                 | AnchorStyles.Bottom
72                 | AnchorStyles.Left
73                 | AnchorStyles.Right;
74             TvList.LabelEdit = true;
75             TvList.ShowPlusMinus = false;
76             TvList.HideSelection = false;
77             TvList.Indent = 15;
78             TvList.ShowRootLines = false;
79             TvList.ShowLines = false;
80             TvList.ContextMenu = CntxtMenu;
81 
82             BtnUp.AccessibleName = SR.GetString(SR.EditableTreeList_MoveUpName);
83             BtnUp.AccessibleDescription = SR.GetString(SR.EditableTreeList_MoveUpDescription);
84             BtnUp.Name = SR.GetString(SR.EditableTreeList_MoveUpName);
85             BtnUp.Location = new System.Drawing.Point(182, 16);
86             BtnUp.Size = new System.Drawing.Size(28, 27);
87             BtnUp.Anchor = AnchorStyles.Top | AnchorStyles.Right;;
88 
89             BtnDown.AccessibleName = SR.GetString(SR.EditableTreeList_MoveDownName);
90             BtnDown.AccessibleDescription = SR.GetString(SR.EditableTreeList_MoveDownDescription);
91             BtnDown.Name = SR.GetString(SR.EditableTreeList_MoveDownName);
92             BtnDown.Location = new System.Drawing.Point(182, 48);
93             BtnDown.Size = new System.Drawing.Size(28, 27);
94             BtnDown.Anchor = AnchorStyles.Top | AnchorStyles.Right;
95 
96             BtnRemove.AccessibleName = SR.GetString(SR.EditableTreeList_DeleteName);
97             BtnRemove.AccessibleDescription = SR.GetString(SR.EditableTreeList_DeleteDescription);
98             BtnRemove.Name = SR.GetString(SR.EditableTreeList_DeleteName);
99             BtnRemove.Location = new System.Drawing.Point(182, 136);
100             BtnRemove.Size = new System.Drawing.Size(28, 27);
101             BtnRemove.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
102 
103             BtnAdd.AccessibleName = SR.GetString(SR.EditableTreeList_AddName);
104             BtnAdd.AccessibleDescription = SR.GetString(SR.EditableTreeList_AddDescription);
105             BtnAdd.Name = SR.GetString(SR.EditableTreeList_AddName);
106             BtnAdd.Location = new System.Drawing.Point(0, 168);
107             BtnAdd.Size = new System.Drawing.Size(178, 25);
108             BtnAdd.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
109 
110             CntxtMenuItem.Text = SR.GetString(SR.EditableTreeList_Rename);
111             CntxtMenu.MenuItems.Add(CntxtMenuItem);
112 
113             this.Location = new System.Drawing.Point(8, Y);
114             this.Size = new System.Drawing.Size(210, 196);
115 
116             this.Controls.Add(LblTitle);
117             this.Controls.Add(TvList);
118             this.Controls.Add(BtnUp);
119             this.Controls.Add(BtnDown);
120             this.Controls.Add(BtnRemove);
121             this.Controls.Add(BtnAdd);
122 
123             BtnDown.Image = GenericUI.SortDownIcon;
124             BtnUp.Image = GenericUI.SortUpIcon;
125             BtnRemove.Image = GenericUI.DeleteIcon;
126 
127             BtnUp.Click += new EventHandler(MoveSelectedItemUp);
128             BtnDown.Click += new EventHandler(MoveSelectedItemDown);
129             RemoveHandler = new EventHandler(OnRemove);
130             BtnRemove.Click += RemoveHandler;
131             TvList.AfterSelect += new TreeViewEventHandler(OnListSelect);
132             TvList.KeyDown += new KeyEventHandler(OnKeyDown);
133             TvList.MouseUp += new MouseEventHandler(OnListMouseUp);
134             TvList.MouseDown += new MouseEventHandler(OnListMouseDown);
135             CntxtMenu.Popup += new EventHandler(OnPopup);
136             CntxtMenuItem.Click += new EventHandler(OnContextMenuItemClick);
137 
138             UpdateButtonsEnabling();
139 
140             if(!showAddButton)
141             {
142                 // stretch UI to occupy space where add button was.
143                 BtnAdd.Visible = false;
144                 int offset = 4 + BtnAdd.Height;
145                 TvList.Height += offset;
146                 BtnRemove.Top += offset;
147             }
148             _caseSensitive = caseSensitive;
149         }
150 
151         ////////////////////////////////////////////////////////////////////////
152         //  End Windes Generated
153         ////////////////////////////////////////////////////////////////////////
154 
155         internal int SelectedIndex
156         {
157             get
158             {
159                 TreeNode selectedNode = TvList.SelectedNode;
160                 if(selectedNode != null)
161                 {
162                     return selectedNode.Index;
163                 }
164                 else
165                 {
166                     return -1;
167                 }
168             }
169         }
170 
171         internal TreeNode SelectedNode
172         {
173             get
174             {
175                 return TvList.SelectedNode;
176             }
177         }
178 
179         private TreeNode SelectedNodeChecked
180         {
181             get
182             {
183                 TreeNode node = TvList.SelectedNode;
184                 Debug.Assert(
185                     node != null,
186                     _assertMsgNullNodeSelected
187                 );
188                 return node;
189             }
190         }
191 
MoveSelectedNode(int direction)192         private void MoveSelectedNode(int direction)
193         {
194             Debug.Assert(direction == 1 || direction == -1);
195             LastNodeChanged = TvList.SelectedNode;
196             Debug.Assert(
197                 LastNodeChanged != null,
198                 _assertMsgNullNodeSelected
199             );
200             int index = LastNodeChanged.Index;
201             Debug.Assert(
202                 (index + direction >= 0)
203                 && ((index + direction) < TvList.Nodes.Count),
204                 _assertMsgOutOfBounds
205             );
206             TvList.Nodes.RemoveAt(index);
207             TvList.Nodes.Insert(index + direction, LastNodeChanged);
208             TvList.SelectedNode = LastNodeChanged;
209         }
210 
MoveSelectedItemUp(Object sender, EventArgs e)211         internal void MoveSelectedItemUp(Object sender, EventArgs e)
212         {
213             MoveSelectedNode(-1);
214             UpdateButtonsEnabling();
215         }
216 
MoveSelectedItemDown(Object sender, EventArgs e)217         internal void MoveSelectedItemDown(Object sender, EventArgs e)
218         {
219             MoveSelectedNode(1);
220             UpdateButtonsEnabling();
221         }
222 
RemoveSelectedItem()223         internal void RemoveSelectedItem()
224         {
225             LastNodeChanged = SelectedNodeChecked;
226             TvList.Nodes.Remove(LastNodeChanged);
227             UpdateButtonsEnabling();
228         }
229 
OnKeyDown(Object sender, KeyEventArgs e)230         private void OnKeyDown(Object sender, KeyEventArgs e)
231         {
232             switch(e.KeyData)
233             {
234                 case Keys.F2:
235                 {
236                     TreeNode selectedNode = TvList.SelectedNode;
237                     if(selectedNode != null)
238                     {
239                         selectedNode.BeginEdit();
240                     }
241                     break;
242                 }
243                 case (Keys.Control | Keys.Home):
244                 {
245                     if(TvList.Nodes.Count > 0)
246                     {
247                         TvList.SelectedNode = TvList.Nodes[0];
248                     }
249                     break;
250                 }
251                 case (Keys.Control | Keys.End):
252                 {
253                     int numNodes = TvList.Nodes.Count;
254                     if(numNodes > 0)
255                     {
256                         TvList.SelectedNode = TvList.Nodes[numNodes - 1];
257                     }
258                     break;
259                 }
260             }
261         }
262 
OnRemove(Object sender, EventArgs e)263         private void OnRemove(Object sender, EventArgs e)
264         {
265             RemoveSelectedItem();
266         }
267 
OnListSelect(Object sender, TreeViewEventArgs e)268         private void OnListSelect(Object sender, TreeViewEventArgs e)
269         {
270             UpdateButtonsEnabling();
271         }
272 
OnListMouseUp(Object sender, MouseEventArgs e)273         private void OnListMouseUp(Object sender, MouseEventArgs e)
274         {
275             EditCandidateNode= null;
276             if (e.Button == MouseButtons.Right)
277             {
278                 EditCandidateNode = (TreeNode)TvList.GetNodeAt (e.X, e.Y);
279             }
280         }
281 
OnListMouseDown(Object sender, MouseEventArgs e)282         private void OnListMouseDown(Object sender, MouseEventArgs e)
283         {
284             EditCandidateNode = null;
285             if (e.Button == MouseButtons.Right)
286             {
287                 EditCandidateNode = (TreeNode)TvList.GetNodeAt (e.X, e.Y);
288             }
289         }
290 
OnPopup(Object sender, EventArgs e)291         private void OnPopup(Object sender, EventArgs e)
292         {
293             CntxtMenuItem.Enabled = (EditCandidateNode != null ||
294                                                     TvList.SelectedNode != null);
295         }
296 
OnContextMenuItemClick(Object sender, EventArgs e)297         private void OnContextMenuItemClick(Object sender, EventArgs e)
298         {
299             if(EditCandidateNode == null)
300             {
301                // context menu key pressed
302                if (TvList.SelectedNode!=null)
303                {
304                     TvList.SelectedNode.BeginEdit();
305                }
306             }
307             else
308             {
309                 // right mouse-click
310                 EditCandidateNode.BeginEdit();
311             }
312             EditCandidateNode = null;
313         }
314 
GetUniqueLabel(String label)315         internal String GetUniqueLabel(String label)
316         {
317             int index = 1;
318             String uniqueLabel = label + index;
319             while(LabelExists(uniqueLabel))
320             {
321                 uniqueLabel = label + (++index);
322             }
323             return uniqueLabel;
324         }
325 
LabelExists(String label)326         internal bool LabelExists(String label)
327         {
328             foreach(TreeNode node in TvList.Nodes)
329             {
330                 if(String.Compare(node.Text, label, ((!_caseSensitive) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) == 0)
331                 {
332                     return true;
333                 }
334             }
335             return false;
336         }
337 
UpdateButtonsEnabling()338         internal void UpdateButtonsEnabling()
339         {
340             int selectedIndex = SelectedIndex;
341             bool anItemIsSelected = (selectedIndex >= 0);
342 
343             BtnRemove.Enabled = anItemIsSelected;
344             if (anItemIsSelected)
345             {
346                 BtnUp.Enabled = (selectedIndex > 0);
347                 BtnDown.Enabled = (selectedIndex < TvList.Nodes.Count - 1);
348             }
349             else
350             {
351                 BtnUp.Enabled = false;
352                 BtnDown.Enabled = false;
353             }
354         }
355     }
356 }
357