Winform中如何实现下拉树效果(类似于ComboBox下拉时显示的是树状结构)

Winform中如何实现下拉树效果

简介:Winform中如何实现下拉树效果(类似于ComboBox下拉时显示的是树状结构),

        如果是BS的WebForm就有很多解决方案了,Devexpress就更方便,利用DropdownList和TreeView去组合控件实现

        但是CS中的Winform的传统窗体控件和Devexpress里面去实现此功能就比较麻烦了

        而此文,我们要讲解的就是如何利用Winform的传统用户控件去实现下拉树的效果

       主要利用TextBox,TreeView,Button等控件事件组合而成类似于ComboBox下拉出现树状结构

       下面就看看我们要实现的下拉树的效果图:

说明:上图所示的就是我们要实现的效果当点击下拉控件时,出现一个树状结构,

         当我们选择树节点时(双击),把相应的节点值,放入上面的文本框中

         好了,下面我们就马上去看看,这样的功能是如何实现的呢?

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

首先我们需要建立一个用户控件,如图:

说明:不需要再进行任何操作

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来,我们需要放一张图片文件,这张图片文件是为了模拟下拉框右边的三角下拉按钮用的,如图:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来就是完全的代码模块了,就这样的界面操作,是如何让我们做到下拉树效果的呢?

在用户控件窗体CS文件中,我们需要添加如下代码:

一.自定义成员变量

二.内部辅助方法

三.对TextBox的事件处理

四.对TreeView的事件处理

五.对Button的事件处理

六.对自身的事件处理

七.外部属性封装

八.构造函数

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

别看上面说的步骤很多,其实加起来也就几百行代码,也没有什么难点,接下来我们就依次展示我们八大步骤模块的代码:

一.自定义成员变量 

        #region 自定义成员变量

        private TextBox m_TextBox;
        private TreeView m_TreeView;
        private Button m_DropdownButton;
        private int m_MaxDropDownItems = 8;
        //是否正在显示下拉列表
        private bool b_Dropdown = false;
        //使能
        private bool b_Enabled = true;
        //事件
        public event EventHandler DropDown;
        public event EventHandler DropDownClosed;
        public event EventHandler EnableChanged;
        public event TreeViewCancelEventHandler BeforeExpand;
        public event TreeViewCancelEventHandler BeforeCollapse;
        public event TreeViewEventHandler AfterExpand;
        public event TreeViewEventHandler AfterCollapse;

        #endregion

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二.内部辅助方法

        #region 内部辅助方法

        /// <summary>
        /// 创建并初始化所有控件,包括添加事件处理函数
        /// </summary>
        /// <author>PengZhen</author>
        /// <time>2013-11-1 13:29:37</time>
        private void InitControls()
        {
            //TextBox
            this.m_TextBox = new TextBox();
            this.m_TextBox.KeyDown += new KeyEventHandler(m_TextBox_KeyDown);
            this.m_TextBox.Parent = this;

            //Button
            this.m_DropdownButton = new Button();
            //Assembly asm = Assembly.GetExecutingAssembly();
            //System.IO.Stream stream = asm.GetManifestResourceStream(asm.GetName().Name + ".BM_dropdown.bmp");
            Bitmap bm = new Bitmap(this.GetType(), "BM_dropdown.bmp");
            this.m_DropdownButton.Image = bm;
            this.m_DropdownButton.Width = 16;
            this.m_DropdownButton.Height = this.m_TextBox.Height - 2;
            this.m_DropdownButton.Location = new Point(this.m_TextBox.Right - 18, 1);
            this.m_DropdownButton.Click += new EventHandler(m_DropdownButton_Click);
            this.m_DropdownButton.FlatStyle = FlatStyle.Flat;
            this.m_DropdownButton.Parent = this;
            this.m_DropdownButton.BringToFront();

            //TreeView
            this.m_TreeView = new TreeView();
            this.m_TreeView.Visible = false;
            this.m_TreeView.DoubleClick += new EventHandler(m_TreeView_DoubleClick);
            this.m_TreeView.KeyDown += new KeyEventHandler(m_TreeView_KeyDown);
            this.m_TreeView.LostFocus += new EventHandler(m_TreeView_LostFocus);
            this.m_TreeView.BeforeExpand += new TreeViewCancelEventHandler(m_TreeView_BeforeExpand);
            this.m_TreeView.BeforeCollapse += new TreeViewCancelEventHandler(TreeComboBox_BeforeCollapse);
            this.m_TreeView.AfterExpand += new TreeViewEventHandler(m_TreeView_AfterExpand);
            this.m_TreeView.AfterCollapse += new TreeViewEventHandler(TreeComboBox_AfterCollapse);
            this.m_TreeView.Location = new Point(0, 0);
            this.m_TreeView.Parent = nu
  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Winform combobox默认情况下是不支持触屏上下滑动的,但可以通过自定义控件来实现这个功能。 一种常见的方法是使用自定义的控件去替代原生的Winform combobox控件。这个自定义控件可以继承自ComboBox,并重写其OnDropDown方法,以便在下拉菜单展开添加一个滚动条。 具体步骤如下: 1. 创建一个新的Winform控件,取名为CustomComboBox。 2. 继承自ComboBox,并重写OnDropDown方法,以便在下拉菜单展开添加一个滚动条。 ``` public class CustomComboBox : ComboBox { protected override void OnDropDown(EventArgs e) { base.OnDropDown(e); var handle = SendMessage(this.Handle, CB_GETCOMBOBOXINFO, IntPtr.Zero, IntPtr.Zero); var info = (COMBOBOXINFO)Marshal.PtrToStructure(handle, typeof(COMBOBOXINFO)); var listBoxHandle = info.hwndList; SetWindowLong(listBoxHandle, GWL_STYLE, GetWindowLong(listBoxHandle, GWL_STYLE) | LBS_NOTIFY | WS_VSCROLL); } private const int CB_GETCOMBOBOXINFO = 0x164; private const int GWL_STYLE = -16; private const int LBS_NOTIFY = 0x00000001; private const int WS_VSCROLL = 0x00200000; [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [StructLayout(LayoutKind.Sequential)] private struct COMBOBOXINFO { public int cbSize; public RECT rcItem; public RECT rcButton; public int stateButton; public IntPtr hwndCombo; public IntPtr hwndEdit; public IntPtr hwndList; } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int left, top, right, bottom; } } ``` 3. 在Form使用CustomComboBox,然后在TouchDown事件记录当前触屏的坐标。 ``` public partial class Form1 : Form { private Point _startPoint; public Form1() { InitializeComponent(); } private void customComboBox1_TouchDown(object sender, TouchEventArgs e) { _startPoint = e.Location; } } ``` 4. 在TouchMove事件计算当前触屏滑动的距离,然后根据距离调整下拉菜单的位置。 ``` private void customComboBox1_TouchMove(object sender, TouchEventArgs e) { var distance = e.Location.Y - _startPoint.Y; var dropDownHeight = customComboBox1.DropDownHeight; if (distance > 0) { customComboBox1.DropDownHeight = Math.Min(dropDownHeight + distance, customComboBox1.Items.Count * customComboBox1.ItemHeight); } else { customComboBox1.DropDownHeight = Math.Max(dropDownHeight + distance, customComboBox1.ItemHeight); } } ``` 5. 最后,在Form的Load事件为CustomComboBox的TouchDown和TouchMove事件添加处理程序。 ``` private void Form1_Load(object sender, EventArgs e) { customComboBox1.TouchDown += customComboBox1_TouchDown; customComboBox1.TouchMove += customComboBox1_TouchMove; } ``` 这样,就可以在Winform实现触屏上下滑动combobox下拉部分了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值