繁体   English   中英

多行组合框下拉列表

[英]Multiline combobox dropdown list

我正在尝试找出从选择列表填充地址字段的最佳方法(模糊但请继续阅读)。

布局:

在此处输入图片说明

当我选择地址下拉菜单时,我希望看到一个完整的完整地址列表,例如,街道名称,国家/地区,邮政编码等。但是,请确保您知道,组合仅是一个班轮。

理想方案:

在此处输入图片说明

结果:

在此处输入图片说明

有没有人这样做的方法?

这是完整的解决方案,您可以看到,这正是我想要的。

在此处输入图片说明

ComboBoxEx是从我上次复制的ComboBox派生的类。 这样做的原因是要设置Items容器的高度(DropDownHeight)。 没有它,容器将根据第一个项目的尺寸x no进行计算。 项,并且由于第一个项的高度为零,因此容器的高度为零。 因此,它需要一个新的类。

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeComboBox();
        }

        private ComboxBoxEx cbox1 = new ComboxBoxEx();
        private DataTable items = new DataTable();

        private void InitializeComboBox()
        {
            items.Columns.AddRange(new DataColumn[] { new DataColumn("id"), new DataColumn("name"), new DataColumn("address") });

            items.Rows.Add(new object[] { 0, "[Please choose an address]", "" });
            items.Rows.Add(new object[] { 1, "Country", "Country" });
            items.Rows.Add(new object[] { 2, "House name", "House name\nStreet name\nTown name\nPostcode\nCountry" });
            items.Rows.Add(new object[] { 3, "House name", "House name\nStreet name\nTown name\nPostcode\nCountry" });

            cbox1.Location = new Point(39, 20);
            cbox1.Size = new System.Drawing.Size(198, 21);
            cbox1.DrawMode = DrawMode.OwnerDrawVariable;
            cbox1.DrawItem += new DrawItemEventHandler(comboBox2_DrawItem);
            cbox1.MeasureItem += new MeasureItemEventHandler(comboBox2_MeasureItem);
            cbox1.SelectedIndexChanged += new EventHandler(comboBox2_SelectedIndexChanged);
            //cbox1.DropDownWidth = 250;
            //cbox1.DropDownHeight = 300;
            //cbox1.MaxDropDownItems = 6;
            this.Controls.Add(cbox1);

            cbox1.ValueMember = "id";
            cbox1.DisplayMember = "name";
            cbox1.DataSource = new BindingSource(items, null);
            //cbox1.SelectedIndex = -1;
        }

        private void comboBox2_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            ComboxBoxEx cbox = (ComboxBoxEx)sender;
            DataRowView item = (DataRowView)cbox.Items[e.Index];
            string txt = item["address"].ToString();

            int height = Convert.ToInt32(e.Graphics.MeasureString(txt, cbox.Font).Height);

            e.ItemHeight = height + 4;
            e.ItemWidth = cbox.DropDownWidth;

            cbox.ItemHeights.Add(e.ItemHeight);
        }

        private void comboBox2_DrawItem(object sender, DrawItemEventArgs e)
        {
            ComboxBoxEx cbox = (ComboxBoxEx)sender;
            DataRowView item = (DataRowView)cbox.Items[e.Index];
            string txt = item["address"].ToString();

            e.DrawBackground();
            e.Graphics.DrawString(txt, cbox.Font, System.Drawing.Brushes.Black, new RectangleF(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height));
            e.Graphics.DrawLine(new Pen(Color.LightGray), e.Bounds.X, e.Bounds.Top + e.Bounds.Height - 1, e.Bounds.Width, e.Bounds.Top + e.Bounds.Height - 1);
            e.DrawFocusRectangle();
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboxBoxEx cbox = (ComboxBoxEx)sender;
            if (cbox.SelectedItem == null) return;

            DataRowView item = (DataRowView)cbox.SelectedItem;
            //label1.Text = item["id"].ToString();
        }
    }
}

ComboBoxEx类

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace WindowsFormsApplication1
{
    public partial class ComboxBoxEx : ComboBox
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // x position of upper-left corner 
            public int Top;         // y position of upper-left corner 
            public int Right;       // x position of lower-right corner 
            public int Bottom;      // y position of lower-right corner 
        }

        public const int SWP_NOZORDER = 0x0004;
        public const int SWP_NOACTIVATE = 0x0010;
        public const int SWP_FRAMECHANGED = 0x0020;
        public const int SWP_NOOWNERZORDER = 0x0200;

        public const int WM_CTLCOLORLISTBOX = 0x0134;

        private int _hwndDropDown = 0;

        internal List<int> ItemHeights = new List<int>();

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_CTLCOLORLISTBOX)
            {
                if (_hwndDropDown == 0)
                {
                    _hwndDropDown = m.LParam.ToInt32();

                    RECT r;
                    GetWindowRect((IntPtr)_hwndDropDown, out r);

                    int newHeight = 0;
                    int n = (Items.Count > MaxDropDownItems) ? MaxDropDownItems : Items.Count;
                    for (int i = 0; i < n; i++)
                    {
                        newHeight += ItemHeights[i];
                    }
                    newHeight += 5; //to stop scrollbars showing

                    SetWindowPos((IntPtr)_hwndDropDown, IntPtr.Zero,
                        r.Left,
                                 r.Top,
                                 DropDownWidth,
                                 newHeight,
                                 SWP_FRAMECHANGED |
                                     SWP_NOACTIVATE |
                                     SWP_NOZORDER |
                                     SWP_NOOWNERZORDER);
                }
            }

            base.WndProc(ref m);
        }

        protected override void OnDropDownClosed(EventArgs e)
        {
            _hwndDropDown = 0;
            base.OnDropDownClosed(e);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM