把下面代码新建一个类,支持ctrl和shift添加.
参见http://www.cnblogs.com/zhangronghua/archive/2011/11/23/CustomTreeViewToSupportDragAndMultiSelect.html
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Text;
namespace WindowsApplication12
{
public delegate void TreeNodeDoubleClickHandle(object sender, EventArgs args);
public delegate void TreeNodeChangedHandle(object sender, EventArgs args);
/// <summary>
/// WITPLMMultiSelectTreeView 的摘要说明。
/// </summary>
[Serializable]
public class WITPLMMultiSelectTreeView : TreeView
{
public event TreeNodeDoubleClickHandle TreeNodeDoubleClick;
public event TreeNodeChangedHandle TreeNodeChanged;
private ArrayList selectedNodes = new ArrayList();
private bool isMulSelect = false;
private TreeNode currentNode = null;
public WITPLMMultiSelectTreeView()
{
}
public virtual void Initialize()
{
this.Sorted = false;
this.ShowRootLines = false;
this.Indent = 15;
this.ItemHeight = 18;
// this.ImageList = PLMService.ResourceService.ImageList;
}
/// <summary>
/// 获取当前节点
/// </summary>
public TreeNode CurrentNode
{
get
{
return currentNode;
}
}
/// <summary>
/// 获取所选节点组
/// </summary>
public ArrayList SelectedNodes
{
get
{
return selectedNodes;
}
}
/// <summary>
/// 判断是否是多选
/// </summary>
public bool IsMulSelect
{
get
{
return isMulSelect;
}
set
{
isMulSelect = value;
}
}
/// <summary>
/// 显示节点菜单
/// </summary>
protected virtual void ShowTreeNodeContextMenu()
{ }
/// <summary>
/// 显示树菜单
/// </summary>
protected virtual void ShowTreeViewContextMenu()
{ }
/// <summary>
/// 检测鼠标单击事件
/// </summary>
/// <param name= "e "> </param>
protected override void OnMouseDown(MouseEventArgs e)
{
TreeNode node = GetNodeAt(e.X, e.Y);
if (node != null)
{
if (isMulSelect)
{
if (!(selectedNodes.Count == 1 && selectedNodes[0] == node))
{
if ((Control.ModifierKeys & Keys.Control) != 0)
{
MulSelectNode(node, e.Button == MouseButtons.Right);
}
else if ((Control.ModifierKeys & Keys.Shift) != 0)
{
shiftMultiSelectNodes (node);
}
else
{
SingleSelectNode(node);
}
}
}
else
SetCurrentNode(node);
}
if (e.Button == MouseButtons.Right)
{
if (node == null)
ShowTreeViewContextMenu();
else
ShowTreeNodeContextMenu();
}
else if (e.Clicks == 2 && node != null)
{
if (TreeNodeDoubleClick != null)
TreeNodeDoubleClick(node, EventArgs.Empty);
}
}
/// <summary>
/// 节点选择改变后执行
/// </summary>
/// <param name= "e "> </param>
protected override void OnAfterSelect(TreeViewEventArgs e)
{
SetCurrentNode(e.Node);
base.OnAfterSelect(e);
}
/// <summary>
/// 复选
/// </summary>
/// <param name= "node "> </param>
/// <param name= "mustSelect "> </param>
private void MulSelectNode(TreeNode node, bool mustSelect)
{
//原理,之前有的就取消,没有就添加上,并处理高亮
if (selectedNodes.Contains(node) && !mustSelect)
{
selectedNodes.Remove(node);
LowlightNode(node);
SetCurrentNode((TreeNode)selectedNodes[selectedNodes.Count - 1]);
}
else
{
selectedNodes.Add(node);
HighlightNode(node);
SetCurrentNode(node);
}
}
///<summary>
/// 按shift键多选的方法
///</summary>
///<param name="node"></param>
private void shiftMultiSelectNodes(TreeNode node)
{
//shift特征变化很大,每选第二个,都会选中与第一个之间的所有,如果中间已经包含,不再添加
if (SelectedNodes.Count == 0)//带上shift选择的第一个
{
selectedNodes.Add(node);
HighlightNode(node);
SetCurrentNode(node);
}
else//带上shift选择的第n个
{
if (node == CurrentNode)//重复shifit点上一个选中node就return
{
return;
}
else if (node.Parent != CurrentNode.Parent)//技术限制,需限制到一个父类下
{
return;
}
else//符合要求
{
TreeNode addNode = node;
for (int i = System.Math.Abs(currentNode.Index - node.Index); i > 0; i--)
{
if (!selectedNodes.Contains(addNode))
{
selectedNodes.Add(addNode);
HighlightNode(addNode);
}
addNode = currentNode.Index > node.Index ? addNode.NextNode : addNode.PrevNode;
}
SetCurrentNode(node);
}
}
}
/// <summary>
/// 单选
/// </summary>
/// <param name= "node "> </param>
private void SingleSelectNode(TreeNode node)
{
foreach (TreeNode nd in SelectedNodes)
{
nd.BackColor = BackColor;
nd.ForeColor = ForeColor;
}
SelectedNodes.Clear();
SelectedNodes.Add(node);
HighlightNode(node);
SetCurrentNode(node);
}
/// <summary>
/// 设置当前节点
/// </summary>
/// <param name= "node "> </param>
private void SetCurrentNode(TreeNode node)
{
if (isMulSelect)
SelectedNode = null;
if (currentNode != node)
{
currentNode = node as TreeNode;
if (TreeNodeChanged != null)
TreeNodeChanged(currentNode, EventArgs.Empty);
// if(currentNode.Component != null)
// currentNode.Component.FireOperation(new ComponentOperationArgs(ComponentOperation.Selected));
}
}
/// <summary>
/// 取消当前节点的高亮显示
/// </summary>
/// <param name= "node "> </param>
private void LowlightNode(TreeNode node)
{
node.BackColor = BackColor;
node.ForeColor = SystemColors.ControlText;
}
/// <summary>
/// 高亮显示节点
/// </summary>
/// <param name= "node "> </param>
private void HighlightNode(TreeNode node)
{
node.BackColor = SystemColors.Highlight;
node.ForeColor = SystemColors.HighlightText;
}
}
}