Treeview多选

最近客户提出一个需求,无法忍受通过checkbox来实现treeview多选.而必须改用统一的 ctrl,shift.

参照了csdn上的几篇文章后,实现了这样的treeview.

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Text;

namespace MyTreeview
{
public delegate void TreeNodeChangedHandle(object sender, EventArgs args);

/// <summary>
/// MultiSelectTreeView design by terro
/// </summary>
[Serializable]
public class MultiSelectTreeView : TreeView
{

public event TreeNodeChangedHandle TreeNodeChanged;

private ArrayList selectedNodes = new ArrayList();
private bool isMulSelect = false;
private TreeNode CurrentNode = null;

public MultiSelectTreeView()
{

}

public virtual void Initialize()
{
this.Sorted = false;
this.ShowRootLines = false;
this.Indent = 15;
this.ItemHeight = 18;
}

/// <summary>
/// Get currnent node,readonly.don't use the SelectNode to get the select node
/// </summary>
public TreeNode CurrentNode
{
get
{
return currentNode;
}
}

/// <summary>
/// Get all the select nodes
/// </summary>
public ArrayList SelectedNodes
{
get
{
return selectedNodes;
}
}

/// <summary>
/// if the control allow mulselct
/// </summary>
public bool IsMulSelect
{
get
{
return isMulSelect;
}
set
{
isMulSelect = value;
}
}

/// <summary>
/// onclick
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(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 || e.Button == MouseButtons.Right)
MulSelectNode(node, e.Button == MouseButtons.Right);
else if ((Control.ModifierKeys & Keys.Shift) != 0)
ShiftMulSelectNode(node, e.Button == MouseButtons.Right);
else
SingleSelectNode(node);
}
}
else
SetCurrentNode(node);
}
}

/// <summary>
/// excuse when after clicking
/// </summary>
/// <param name="e"></param>
protected override void OnAfterSelect(TreeViewEventArgs e)
{
SetCurrentNode(e.Node);
base.OnAfterCheck(e);
}

/// <summary>
/// MulSelect
/// </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 if(!mustSelect)
{
selectedNodes.Add(node);
HighlightNode(node);
SetCurrentNode(node);
}
}

/// <summary>
/// ShiftMulSelectNode
/// </summary>
/// <param name="node"></param>
/// <param name="mustSelec"></param>
private void ShiftMulSelectNode(TreeNode node, bool mustSelect)
{
if (selectedNodes.Contains(node) && !mustSelect)
{
selectedNodes.Remove(node);
LowlightNode(node);
SetCurrentNode((TreeNode)selectedNodes[selectedNodes.Count - 1]);
}
else if (node.Parent == currentNode.Parent && !mustSelect)
{
TreeNode addNode = node;
for (int i = System.Math.Abs(currentNode.Index - node.Index); i > 0; i--)
{
if (!selectedNodes.Contains((object)addNode))
{
selectedNodes.Add(addNode);
HighlightNode(addNode);
}

addNode = currentNode.Index > node.Index ? addNode.NextNode : addNode.PrevNode;
}

SetCurrentNode(node);
}
}

/// <summary>
/// single select
/// </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>
/// Set current node
/// </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);
}
}

/// <summary>
/// cancel the light
/// </summary>
/// <param name="node"></param>
private void LowlightNode(TreeNode node)
{
node.BackColor = BackColor;
node.ForeColor = SystemColors.ControlText;
}

/// <summary>
/// set the light
/// </summary>
/// <param name="node"></param>
private void HighlightNode(TreeNode node)
{
node.BackColor = SystemColors.Highlight;
node.ForeColor = SystemColors.HighlightText;
}

}
}

在用shift选择不同父树的子树时,第一次选择会被屏蔽,因为这样不能获取到树的结构关系.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值