最近客户提出一个需求,无法忍受通过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选择不同父树的子树时,第一次选择会被屏蔽,因为这样不能获取到树的结构关系.
参照了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选择不同父树的子树时,第一次选择会被屏蔽,因为这样不能获取到树的结构关系.
相关推荐
C# TreeView 多选
一个实例工程,包括如何实现TreeView多选功能,如何绘制TreeNode底板、改变节点样式、绘制字体,如何在TreeNode后面添加Button按钮。
java treeview 多选和获取值, 你懂的。
本版本是aceadmin1.4完整版,针对treeview多选支持不好的问题进行过改造。 效果请参看:https://blog.csdn.net/ohaozy/article/details/81415384
在一个前辈的代码基础上修改的,他的下载回来后,发现在按shift多选时会出错,故在其基础上修改。
自己实现treeview,支持单选和多选,带checkbox,感兴趣的童鞋可以下载看看
重写TreeView按住Shift或ctrl进行多选
重写WinForm控件中的TreeView控件,实现了TreeView多选,里面有源代码(vs2010开发的)。可以像Windows中那样用Shift多个选择节点,也可以用Ctrl单个多选节点。压缩包中有源码和示例文件夹(TreeView使用文件夹和文件...
WPF 自定义 树形选择框,Combox+TreeView 实现,支持多选,自定义样式
winform实现多选树,以及获取选中的树,包含选中父树时全选子树,选中取消,子树取消。选中子树自动选中父树,比较适合做权限等管理。
一个功能更加强大的TreeView组件,支持图形、树列表、拖放等功能。
一个TreeView控件,它以不同的方式实现多项选择
在Qt5.5之前是没有树控件的,我们在使用时用的是ListView来构造出一个树,Qt5.5之后的QML开发阶段,有了树控件TreeView,本篇着重记录QML的TreeView的使用(包括增加树节点和删除节点)。
js实现treeview全选,javascript 脚本,加入之后轻松实现treeview的级联选中
这个是最好的
Treeview 绑定数据库。附有详细注释哦。很多c#的常规应用哦。可以试着去看看代码学习学习。对自己很有用的哦。
delphi 的Treeview与数据库的联合使用实例access
树控件 TreeView Shift Ctrl 实现多选功能 动态操作树控件
纯JQuery实现TreeView示例带连接虚线|多选框,需要的朋友多多支持!
TreeView+MVVM实现TreeView“多选”,使用MVVM模式和依赖属性