Продолжая тему написания различных элементов управления, рассмотрим TreeView с возможностью выделения нескольких узлов, за основу также был взят существующий проект (http://www.codeproject.com), который был доработан и несколько видоизменён:
- выделение происходит только при зажатой клавише Ctrl
- при выборе обновляется только текущий узел, а не все узлы
- исправлена ошибка, когда нельзя было выделить последний выбранный узел

Исходный код: MultiSelectTreeViewExample (zip, 5.60 Кб)
При выделении узел из дерева помещается в список узлов SelectedNodes, при этом происходит отмена выбора в обработчике события OnBeforeSelect и выбранный узел SelectedNode всегда остается нулевым (null). Таким образом событие OnBeforeSelect вызывается даже при выборе текущего узла, чего нельзя было сделать в первоначальном проекте.
Описание класса:
1 using System.Collections.Generic;
2 using System.ComponentModel;
3 using System.Drawing;
4
5 namespace System.Windows.Forms
6 {
7 /// <summary>
8 /// TreeView with multiselect feature
9 /// </summary>
10 public partial class MultiSelectTreeView : TreeView
11 {
12 #region Members
13
14 private List<TreeNode> m_SelectedNodes = new List<TreeNode>();
15
16 #endregion
17
18 #region Properties
19
20 /// <summary>
21 /// List of selected nodes
22 /// </summary>
23 [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
24 public List<TreeNode> SelectedNodes
25 {
26 get { return m_SelectedNodes; }
27 set
28 {
29 BeginUpdate();
30
31 for (int i = m_SelectedNodes.Count - 1; i >= 0; --i)
32 removeSelectedNode(m_SelectedNodes[i]);
33 for (int i = value.Count - 1; i >= 0; --i)
34 addSelectedNode(value[i]);
35
36 EndUpdate();
37 }
38 }
39
40 #endregion
41
42 #region Overrides
43
44 /// <summary>
45 /// Change selected state for nodes,
46 /// Selection is always cancelled,
47 /// SelectedNode is always null
48 /// </summary>
49 /// <param name="e">A <seealso cref="System.Windows.Forms.TreeViewCancelEventArgs"/> that contains the event data</param>
50 protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
51 {
52 base.OnBeforeSelect(e);
53
54 if (e.Action != TreeViewAction.Unknown)
55 {
56 BeginUpdate();
57
58 if (ModifierKeys == Keys.Control)
59 {
60 if (m_SelectedNodes.Contains(e.Node))
61 removeSelectedNode(e.Node);
62 else
63 addSelectedNode(e.Node);
64 }
65 else
66 {
67 for (int i = m_SelectedNodes.Count - 1; i >= 0; --i)
68 removeSelectedNode(m_SelectedNodes[i]);
69 addSelectedNode(e.Node);
70 }
71
72 EndUpdate();
73 }
74 e.Cancel = true;
75 }
76
77 #endregion
78
79 #region Methods
80
81 /// <summary>
82 /// Add selected node to list
83 /// </summary>
84 /// <param name="node">Selected node</param>
85 protected void addSelectedNode(TreeNode node)
86 {
87 m_SelectedNodes.Add(node);
88 node.BackColor = SystemColors.Highlight;
89 node.ForeColor = SystemColors.HighlightText;
90 }
91
92 /// <summary>
93 /// Remove selected node from list
94 /// </summary>
95 /// <param name="node">Selected node</param>
96 protected void removeSelectedNode(TreeNode node)
97 {
98 node.BackColor = BackColor;
99 node.ForeColor = ForeColor;
100 m_SelectedNodes.Remove(node);
101 }
102
103 #endregion
104 }
105 }
Рубрика: Visual Studio