csharp:DropDownComboxTreeView

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Resources;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomControls
{


    /// <summary>
    /// 涂聚文 2014-06-30
    /// DropDownTreeView class offers TreeView that is desined to act under a drop down control
    /// You can use this control when you need to select a value from a dynamic TreeView.	
    /// The sub controls of this control are set to protected. You can override the control
    /// to assign values to the subcontrol of change their behaviour. 	
    /// http://www.codeproject.com/Articles/3994/Custom-ComboBoxes-with-Advanced-Drop-down-Features
    /// </summary>
    public class DropDownComboxTreeView : UserControl
    {
        /// <summary>
        /// protected Button control, this is the control's toggle button
        /// </summary>
        protected ButtonEx btnSelect;
        /// <summary>
        /// protected TextBox control, this is control's value TextBox.
        /// The TextBox's ReadyOnly false is by default set ti true
        /// </summary>
        protected ComboBox useComboxBox;
        /// <summary>
        /// protected TreeView control, this is the control's TreeView.
        /// </summary>
        protected TreeView treeView;

        /// <summary>
        /// protected value that is set to true of false within the
        ///  SetTextValueToSelectedNode method.
        /// </summary>
        protected bool TextValueSet=false;

        /// <summary>
        /// the resize label on the Control's TreeView control
        /// </summary>
        private LabelEx treeLabel;

        /// <summary>
        /// This is the margin in pixels for resizing the TreeView
        /// </summary>
        private int Margin = 10;

        /// <summary>
        /// TreeView's minimum width
        /// </summary>
        private int tvMinWidth = 0;

        /// <summary>
        /// TreeView's minimum height
        /// </summary>
        private int tvMinHeight = 150;

        //private ComboBox.ObjectCollection itm;

        /// <summary>
        /// General point to access MouseMove event for resizing the TreeView
        /// </summary>
        private MouseEventArgs parentMouse;

       // ComboboxItem item = null;

        //private string _Text;

        //        public string ComboxText
        //        {
        //            get { return _Text; }
        //            set { _Text = value; }
        //        }
        //private string _Value;

        //        public string ComboxValue
        //        {
        //            get { return _Value; }
        //            set { _Value = value; }
        //        }
      
        /// <summary>
        /// Get TreeNodeCollection collection, Herewith you can add and remove items to the treeview
        /// </summary>
        [
            Description("Gets the TreeView Nodes collection"),
            Category("TreeView")
        ]
        public TreeNodeCollection Nodes
        {
            get
            {
                return treeView.Nodes;
            }
        }

        /// <summary>
        /// Get,set property that provides the TreeView's Selected Node
        /// </summary>
        [
            Description("Gets or sets the TreeView's Selected Node"),
            Category("TreeView")
        ]
        public TreeNode SelectedNode
        {
            get
            {
                return treeView.SelectedNode;
            }
            set
            {
                treeView.SelectedNode = value;
            }
        }

        /// <summary>
        /// Get, set property of boolean type, this property is mapped to the ReadOnly property of the control's TextBox
        /// </summary>
        [
            Description("Gets or sets the ComboBox's Enabled state"),
            Category("ComboBox")
        ]
        public bool ComboBoxReadOnly
        {
            set
            {
                useComboxBox.Enabled = value;
            }
            get
            {
                return useComboxBox.Enabled;
            }
        }

        //[
        //    Description("Gets or sets the ComboBox's text state"),
        //    Category("ComboBox")
        //]
        //public ComboboxItem Items
        //{
        //    get
        //    {
        //        return object; //txtValue.Items
        //    }
        //    set
        //    {
        //        txtValue.SelectedItem = value;
        //    }
        //}
        /// <summary>
        /// 
        /// </summary>
        //public List<UserCombox>
        //{
        //   List<UserCombox> collection=new List<UserCombox>;
                            
           
        //}
        //public UserCombox Items
        //{
        //    get { }
        //    set { }
        //}

        //[
        //    Description("Gets or sets the ComboBox's text state"),
        //    Category("ComboBox")
        //]
        public ComboBox.ObjectCollection Items 
        {
           //ComboBox.ObjectCollection  items= new ComboBox.ObjectCollection(txtValue); 

            set
            {
                for (int i = 0; i < value.Count; i++)
                {
                    useComboxBox.Items.Add(value[i]);
                }
            }

            get
            {
                //if (Items.Count > 0)
                //{
                //    txtValue.Items.Add(Items);
                //}
                return this.useComboxBox.Items;
            }
        }
        [
            Description("Gets the ComboxBox DataSource"),
            Category("ComboBox")
        ]
        public Object DataSource 
        {         
            set
            { 
                useComboxBox.DataSource = value;  //要先的关系
            } 
            get
            { 
                return useComboxBox.DataSource; 
            }
  
        }
        [
            Description("Gets the ComboxBox DataSource DisplayMember"),
            Category("ComboBox")
        ]
        public string DisplayMember 
        {
            set
            {
                useComboxBox.DisplayMember = value;
            }
            get
            {
                return useComboxBox.DisplayMember;
            } 
        }
        [
            Description("Gets the ComboxBox DataSource ValueMember"),
            Category("ComboBox")
        ]
        public string ValueMember
        {
            set
            {
                useComboxBox.ValueMember = value;
            }
            get
            {
                return useComboxBox.ValueMember;
            } 
        }

  //      public static void SetLookupBinding(ListControl toBind,
  //object dataSource, string displayMember,
  //string valueMember)
  //      {
  //          toBind.DisplayMember = displayMember;
  //          toBind.ValueMember = valueMember;

  //          // Only after the following line will the listbox 
  //          // receive events due to binding.
  //          toBind.DataSource = dataSource;
  //      }

        /// <summary>
        /// Get, set property thai is mapped to the Control's treeView control's ImageList property.
        /// </summary>
        public ImageList Imagelist
        {
            get
            {
                return treeView.ImageList;
            }
            set
            {
                treeView.ImageList = value;
            }
        }
        /// <summary>
        /// Control's constuctor
        /// </summary>
        public DropDownComboxTreeView()
        {
            //item=new ComboboxItem();
            //item.Text = "";// CustomControls.CustComboboxItem.ComboxText;
            //item.Value = "";// CustomControls.CustComboboxItem.ComboxValue;
            // General
            TextValueSet = false;

            // Initializing Controls
            InitControls();

            // Setting The locations
            SetSizeAndLocation();

            // Adding Controls to UserControl
            this.Controls.AddRange(new Control[] { btnSelect, useComboxBox, treeView });

            // attaching events
            this.Resize += new EventHandler(ControlResize);
            this.LocationChanged += new EventHandler(ControlResize);

        }

        /// <summary>
        /// Control's resize handler, this handler is attached to the controls Resize and LocationChanged events
        /// </summary>
        /// <param name="sender">sender obcject</param>
        /// <param name="e">default EventArgs</param>
        private void ControlResize(object sender, EventArgs e)
        {
            // Setting The locations
            SetSizeAndLocation();
        }


        /// <summary>
        /// Controls, sub control initializer, private void that handles the control initialization.
        /// </summary>
        public void InitControls()
        {
            try
            {
                //value box settings;
                useComboxBox = new ComboBox();
                this.ComboBoxReadOnly = true;
                useComboxBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.Simple;
                //初始化的值
                //if (TextValueSet == false)
                //{
                //    ComboboxItem item = new ComboboxItem();
                //    ////txtValue.Text = this.SelectedNode.Text; //设定的值
                //    item.Text = CustComboboxItem.ComboxText;
                //    item.Value = CustComboboxItem.ComboxValue;
                //if (!object.Equals(item, null))
                //{
                //    txtValue.Items.Add(item);
                //    txtValue.SelectedIndex = 0;
                //}

                //}
                //txtValue.Text = "gee";
                //txtValue.Text = "";
                //txtValue.Items.Add(SelecItem);
                if (TextValueSet == false)
                {
                    useComboxBox.DataSource = DataSource;
                    useComboxBox.DisplayMember = DisplayMember;
                    useComboxBox.ValueMember = ValueMember;
                }
                else
                {
                    useComboxBox.DataSource = null;
                }

                useComboxBox.Size = new System.Drawing.Size(121, 18);
                //select button settings
                btnSelect = new ButtonEx();
                //btnSelect.Font = new Font("System",7);
                //btnSelect.Text = "+";
                //btnSelect.TextAlign = ContentAlignment.MiddleCenter;
                //btnSelect.ClientSize = btnSelect.Size;
                btnSelect.Click += new EventHandler(ToggleTreeView);
                //btnSelect.Size = new Size(120,txtValue.Height);


                treeView = new TreeView();
                treeView.BorderStyle = BorderStyle.FixedSingle;
                treeView.Visible = false;
                treeView.AfterSelect += new TreeViewEventHandler(TreeViewNodeSelect);
                treeView.DoubleClick += new EventHandler(TreeViewNodeDoubleClickSelect); //双击为选择
                treeView.MouseMove += new MouseEventHandler(TreeViewMouseMoveEventHandler);
                treeView.Size = new Size(tvMinWidth, tvMinHeight);
                treeLabel = new LabelEx();
                treeLabel.Size = new Size(16, 16);
                treeLabel.BackColor = Color.Transparent;
                treeView.Controls.Add(treeLabel);
                SetHotSpot();

                this.SetStyle(ControlStyles.DoubleBuffer, true);
                this.SetStyle(ControlStyles.ResizeRedraw, true);
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }


        /// <summary>
        /// private void for setting the HotSpot helper label.
        /// </summary>
        private void SetHotSpot()
        {
            treeLabel.Top = treeView.Height - treeLabel.Height;
            treeLabel.Left = treeView.Width - treeLabel.Width;
        }

        /// <summary>
        /// TreeView node select handler, this is a protected event method 
        /// that is attached to the TreeView's AfterSelect event. It sets the 
        /// TextBox's Text property. By default It checks the selected treenode, 
        /// If the treenode dosn't have any child node then, this node's value 
        /// is assigned to the TextBox's Text Property. 
        /// You can implement your own AfterSelect handler by overriding this method.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">default TreeViewEventArgs</param>
        protected void TreeViewNodeSelect(object sender, TreeViewEventArgs e)
        {
            // chiching for none root node
            if (this.SelectedNode.Nodes.Count == 0) //选择确定
            {
                SetTextValueToSelectedNode();
                TextValueSet = true;
            }
        }


        /// <summary>
        /// This event method is the control's TreeView's DoubleClick event handler.
        /// It is meant to close the TreeView when an item is DoubleClicked.
        /// This function calls the TreeViewNodeSelect event handler method, then if 
        /// the TextValueSet is set to true it toggles (closes) the TreeView
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TreeViewNodeDoubleClickSelect(object sender, EventArgs e)
        {
            this.TreeViewNodeSelect(sender, null);
            if (TextValueSet)
            {
                this.ToggleTreeView(sender, null);
            }
        }
        /// <summary>
        /// private void setting the control's TextBox's Text property.
        /// This method also sets the TextValueSet to true if a value 
        /// is assigned to the TextBox's Text property
        /// </summary>
        private void SetTextValueToSelectedNode()
        {
            try
            {
                //useComboxBox.Items.Clear();
                useComboxBox.DataSource = null;
                ComboboxItem item = new ComboboxItem();
                //txtValue.Text = this.SelectedNode.Text; //设定的值
                item.Text = this.SelectedNode.Text;
                item.Value = this.SelectedNode.Name;
                useComboxBox.Items.Clear();
                useComboxBox.Items.Add(item);
                useComboxBox.SelectedIndex = 0;
                TextValueSet = true;
            }
            catch(Exception ex)
            {
                ex.Message.ToString();
                TextValueSet = false;
            }
        }

        /// <summary>
        /// private event method, this method is attached to the control's Button's Clcick event.
        /// It handles the show/hide of the control's treeview
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">default EventArgs</param>
        private void ToggleTreeView(object sender, EventArgs e)
        {
            if (!treeView.Visible)
            {

                SetTreeViewSizeAndLocation();
                try
                {
                    this.btnSelect.Text = "-";
                    this.Parent.Controls.Add(treeView);
                    this.treeView.BringToFront();
                    treeView.Visible = true;
                    treeView.Select();
                    Parent.MouseMove += new MouseEventHandler(ParentMouseMoveHandler);
                    if (treeView.Width < this.Width || treeView.Height < this.Height)
                    {
                        treeView.Width = tvMinWidth;
                        treeView.Height = 150;
                        SetHotSpot();
                    }

                }
                catch
                {
                }
            }
            else
            {
                try
                {
                    btnSelect.Text = "+";
                    treeView.Visible = false;
                    this.Parent.Controls.Remove(treeView);
                    Parent.MouseMove -= new MouseEventHandler(ParentMouseMoveHandler);
                }
                catch
                {
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TreeViewMouseMoveEventHandler(object sender, MouseEventArgs e)
        {
            this.parentMouse = e;
            SetCursor(Cursors.Default);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ParentMouseMoveHandler(object sender, MouseEventArgs e)
        {
            int tx, ty;
            this.parentMouse = e;

            tx = treeView.Left + treeView.Width;
            ty = treeView.Top + treeView.Height;

            SetHotSpot();

            if (e.Button == MouseButtons.Left)
            {
                Margin = 50;
                treeLabel.BringToFront();
            }
            else
            {
                Margin = 4;
            }

            if ((is_in_range(e.Y, ty - Margin, ty + Margin)) && is_in_range(e.X, tx - Margin, tx + Margin))
            {
                SetCursor(Cursors.SizeNWSE);
                if (e.Button == MouseButtons.Left)
                {
                    treeView.Height = e.Y - treeView.Top;
                    treeView.Width = e.X - treeView.Left;
                }
            }
            else
            {
                SetCursor(Cursors.Default);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="crs"></param>
        private void SetCursor(Cursor crs)
        {
            treeView.Cursor = crs;
            Parent.Cursor = crs;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rvalue"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private bool is_in_range(int rvalue, int start, int end)
        {
            if ((rvalue >= start) && (rvalue <= end))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void SetTreeViewMinimumSize()
        {
            if ((treeView.Width < this.Width) || (treeView.Height < 150))
            {
                treeView.Width = this.Width;
                treeView.Height = 150;
            }
        }

        /// <summary>
        /// private method sets the control's TreeView's size and location.
        /// It is called when the control is resized to moved from it's place
        /// </summary>
        private void SetTreeViewSizeAndLocation()
        {
            if (treeView != null)
            {
                treeView.Location = new Point(this.Left, this.Top + this.Height + 1);
            }
        }

        /// <summary>
        /// private method, sets the controls size and location. 
        /// It sets the control's and sub control's sizes and locations
        /// </summary>
        private void SetSizeAndLocation()
        {
            tvMinWidth = this.Width;
            if (useComboxBox != null && btnSelect != null)
            {
                btnSelect.Size = new Size(useComboxBox.Height, 18);
                useComboxBox.Width = this.Width - btnSelect.Width - 4;
                useComboxBox.Location = new Point(0, 0);
                btnSelect.Left = useComboxBox.Width + 4;
                SetTreeViewSizeAndLocation();
                this.Height = useComboxBox.Height;
            }
        }
    }


    /// <summary>
    /// Extended Label control with user paint.
    /// </summary>
    public class LabelEx : Label
    {
        /// <summary>
        /// 
        /// </summary>
        public LabelEx()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            System.Windows.Forms.ControlPaint.DrawSizeGrip(e.Graphics, Color.Black, 0, 0, 16, 16);
        }
    }


    /// <summary>
    /// 
    /// </summary>
    public class ComboboxItem
    {


        string _Text;
        public string Text {
            get { return _Text; }
            set { _Text = value; }
		}
        object _Value;
        public object Value {
            get { return _Value; }
            set { _Value = value; }
		 }

        public override string ToString()
        {
            return Text;
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public  class CustComboboxItem
    {
        public static string ComboxText;
        public static string ComboxValue;
    }
    //private string _Text;

    //        public string ComboxText
    //        {
    //            get { return _Text; }
    //            set { _Text = value; }
    //        }
    //private string _Value;

    //        public string ComboxValue
    //        {
    //            get { return _Value; }
    //            set { _Value = value; }
    //        }
    /// <summary>
    /// Extended button control with userpaint
    /// </summary>
    public class ButtonEx : Button
    {
        ButtonState state;

        /// <summary>
        /// 
        /// </summary>
        public ButtonEx()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            state = ButtonState.Pushed;
            base.OnMouseDown(e);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            state = ButtonState.Normal;
            base.OnMouseUp(e);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            System.Windows.Forms.ControlPaint.DrawComboButton(e.Graphics, 0, 0, this.Width, this.Height, state);
        }
    }
}

 

posted @ 2014-06-30 23:24  ®Geovin Du Dream Park™  阅读(577)  评论(0编辑  收藏  举报