新文章 网摘 文章 随笔 日记

带过滤的Winform自定义下拉列表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Core.WinformUserControllers
{
    public class DropDownFilterTextChangeEventArgs : EventArgs
    {
        public DropDownFilterTextChangeEventArgs(string text)
        {
            Text = text;
        }
        public string Text { get; }
    }
    public partial class DropDownFilter : UserControl
    {
        private KeyValuePair<string, string>[] _dataSource;
        private KeyValuePair<string, string>[] _filteringData;
        private int _oldHeight;
        private bool _isSelectChanging;

        public delegate void TextChangeHandler(object sender, DropDownFilterTextChangeEventArgs e);

        public event TextChangeHandler OnTextChange;

        public void PublishTextChangeMessage(object sender, DropDownFilterTextChangeEventArgs e)
        {
            OnTextChange?.Invoke(sender, e);
        }

        public KeyValuePair<string, string>? Value
        {
            get
            {
                if (LbxDataList.SelectedItem == null)
                {
                    return null;
                }
                var selectItem = (KeyValuePair<string, string>)LbxDataList.SelectedItem;
                return selectItem;
            }
            set
            {
                if (value == null)
                {
                    _isSelectChanging = true;
                    LbxDataList.SelectedItem = null;
                    TbxDisplayText.Text = "";
                    _isSelectChanging = false;
                }
                else
                {
                    _isSelectChanging = true;
                    var selectItem = _dataSource.FirstOrDefault(r => r.Key == ((KeyValuePair<string, string>)value).Key);
                    LbxDataList.SelectedItem = selectItem;
                    TbxDisplayText.Text = selectItem.Value;
                    _isSelectChanging = false;
                }

            }
        }

        public KeyValuePair<string, string>[] DataSource
        {
            get { return _dataSource; }
            set
            {
                _dataSource = value;
                LbxDataList.DataSource = DataSource;
                LbxDataList.DisplayMember = "Value";
                LbxDataList.ValueMember = "Key";
            }
        }

        public DropDownFilter()
        {
            InitializeComponent();
        }

        private void TbxDisplayText_Enter(object sender, EventArgs e)
        {
            LbxDataList.DataSource = _dataSource;
            LbxDataList.Visible = true;
            Height = 200;
        }



        public void DataBind()
        {
            LbxDataList.DataSource = DataSource;
        }

        private void LbxDataList_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void TbxDisplayText_Leave(object sender, EventArgs e)
        {
            Height = _oldHeight;
            LbxDataList.Visible = false;
        }

        private void TbxDisplayText_TextChanged(object sender, EventArgs e)
        {
            if (_isSelectChanging)
            {
                return;
            }
            DropDownFilterTextChangeEventArgs arg = new DropDownFilterTextChangeEventArgs(TbxDisplayText.Text);
            PublishTextChangeMessage(sender, arg);
            if (string.IsNullOrWhiteSpace(TbxDisplayText.Text))
            {
                LbxDataList.DataSource = _dataSource;
            }
            _filteringData = _dataSource?
                .Where(r =>
                    !string.IsNullOrWhiteSpace(r.Value)
                    && r.Value.ToLower().Contains(TbxDisplayText.Text.ToLower()))
                .ToArray();

            LbxDataList.DataSource = _filteringData;

            LbxDataList.SelectedItem = null;
        }

        private void DropDownFilter_Load(object sender, EventArgs e)
        {
            _oldHeight = Height;
        }

        private void TbxDisplayText_Click(object sender, EventArgs e)
        {
            LbxDataList.DataSource = _dataSource;

            if (!LbxDataList.Visible)
            {
                LbxDataList.Visible = true;
                Height = 200;
            }
        }

        private void DropDownFilter_MouseLeave(object sender, EventArgs e)
        {
            Height = _oldHeight;
            LbxDataList.Visible = false;
        }

        private void LbxDataList_MouseClick(object sender, MouseEventArgs e)
        {
            int index = LbxDataList.IndexFromPoint(e.Location);
            if (index != ListBox.NoMatches)
            {
                _isSelectChanging = true;
                var data = (KeyValuePair<string, string>[])LbxDataList.DataSource;
                LbxDataList.SelectedItem = data[index];
                TbxDisplayText.Text = data[index].Value;
                TbxValue.Text = data[index].Key;
                Height = _oldHeight;
                LbxDataList.Visible = false;
                _isSelectChanging = false;
            }
        }

        private void TbxDisplayText_MouseLeave(object sender, EventArgs e)
        {
            var mousePoint = PointToClient(MousePosition);
            var isContain = ClientRectangle.Contains(mousePoint);
            if (!isContain)
            {
                Height = _oldHeight;
                LbxDataList.Visible = false;
            }
        }

        private void LbxDataList_MouseLeave(object sender, EventArgs e)
        {
            var mousePoint = PointToClient(MousePosition);
            var isContain = ClientRectangle.Contains(mousePoint);
            if (!isContain)
            {
                Height = _oldHeight;
                LbxDataList.Visible = false;
            }
        }
    }
}
namespace Core.WinformUserControllers
{
    partial class DropDownFilter
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.TbxDisplayText = new System.Windows.Forms.TextBox();
            this.LbxDataList = new System.Windows.Forms.ListBox();
            this.TbxValue = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // TbxDisplayText
            // 
            this.TbxDisplayText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.TbxDisplayText.Location = new System.Drawing.Point(0, 0);
            this.TbxDisplayText.Margin = new System.Windows.Forms.Padding(0);
            this.TbxDisplayText.Name = "TbxDisplayText";
            this.TbxDisplayText.Size = new System.Drawing.Size(150, 22);
            this.TbxDisplayText.TabIndex = 0;
            this.TbxDisplayText.Click += new System.EventHandler(this.TbxDisplayText_Click);
            this.TbxDisplayText.TextChanged += new System.EventHandler(this.TbxDisplayText_TextChanged);
            this.TbxDisplayText.Enter += new System.EventHandler(this.TbxDisplayText_Enter);
            this.TbxDisplayText.Leave += new System.EventHandler(this.TbxDisplayText_Leave);
            this.TbxDisplayText.MouseLeave += new System.EventHandler(this.TbxDisplayText_MouseLeave);
            // 
            // LbxDataList
            // 
            this.LbxDataList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.LbxDataList.FormattingEnabled = true;
            this.LbxDataList.ItemHeight = 12;
            this.LbxDataList.Location = new System.Drawing.Point(0, 21);
            this.LbxDataList.Margin = new System.Windows.Forms.Padding(0);
            this.LbxDataList.Name = "LbxDataList";
            this.LbxDataList.Size = new System.Drawing.Size(150, 148);
            this.LbxDataList.TabIndex = 1;
            this.LbxDataList.Visible = false;
            this.LbxDataList.MouseClick += new System.Windows.Forms.MouseEventHandler(this.LbxDataList_MouseClick);
            this.LbxDataList.SelectedIndexChanged += new System.EventHandler(this.LbxDataList_SelectedIndexChanged);
            this.LbxDataList.MouseLeave += new System.EventHandler(this.LbxDataList_MouseLeave);
            // 
            // TbxValue
            // 
            this.TbxValue.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.TbxValue.Location = new System.Drawing.Point(0, 174);
            this.TbxValue.Margin = new System.Windows.Forms.Padding(0);
            this.TbxValue.Name = "TbxValue";
            this.TbxValue.Size = new System.Drawing.Size(150, 22);
            this.TbxValue.TabIndex = 2;
            this.TbxValue.Visible = false;
            // 
            // DropDownFilter
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.TbxValue);
            this.Controls.Add(this.LbxDataList);
            this.Controls.Add(this.TbxDisplayText);
            this.Name = "DropDownFilter";
            this.Size = new System.Drawing.Size(150, 200);
            this.Load += new System.EventHandler(this.DropDownFilter_Load);
            this.MouseLeave += new System.EventHandler(this.DropDownFilter_MouseLeave);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox TbxDisplayText;
        private System.Windows.Forms.ListBox LbxDataList;
        private System.Windows.Forms.TextBox TbxValue;
    }
}

 

posted @ 2020-12-16 09:15  岭南春  阅读(290)  评论(0)    收藏  举报