`
liu5320102
  • 浏览: 40447 次
  • 性别: Icon_minigender_1
  • 来自: 南京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Treeview多选

    博客分类:
  • C#
阅读更多
最近客户提出一个需求,无法忍受通过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选择不同父树的子树时,第一次选择会被屏蔽,因为这样不能获取到树的结构关系.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics