六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 44|回复: 0

Treeview多选

[复制链接]

升级  16%

18

主题

18

主题

18

主题

秀才

Rank: 2

积分
74
 楼主| 发表于 2013-2-7 03:51:33 | 显示全部楼层 |阅读模式
最近客户提出一个需求,无法忍受通过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选择不同父树的子树时,第一次选择会被屏蔽,因为这样不能获取到树的结构关系.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表