Windows窗体ComboBox DropDown位置

use*_*630 2 .net c# combobox winforms

在此输入图像描述

通常下拉项目开始位置与开始位置对齐,ComboBox如上图所示.但是我需要开发一个ComboBox控件,它有一个冗长的下拉项目在中间对齐.我的意思是下拉项目左侧位置应该比ComboBox下面的图像更左侧定位.任何帮助将不胜感激.

在此输入图像描述

Rez*_*aei 6

这是一个扩展ComboBox,它有2个新的有用功能,可让您设置下拉列表的位置和大小:

  • DropDownAlignment:您可以将其设置为Left,然后下拉菜单将显示在其正常位置,并且它左侧与控件左侧对齐.如果将其设置为Middle,则下拉菜单的中间将与控件对齐,如果将其设置为Right,则下拉菜单的右侧将与控件权对齐.

  • AutoWidthDropDown:如果将其设置为true,DropdownWidth则将设置为最长项目的宽度.如果您将其设置为false使用Widthas DropDownWidth.

这里是下拉的外观设置后AutoWidthDropDown,以trueDropDownAlignmentLeft,MiddleRight:

剩下

中间

对

实现 - 具有DropDown位置和AutoWith DropDown的ComboBox

您可以处理WM_CTLCOLORLISTBOX消息,lparam是下拉句柄,然后您可以使用设置下拉列表的位置SetWindowPos.

您还可以计算最长项目的宽度,并设置为DropDownWidth如果AutoWidthDropDown为真.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
Run Code Online (Sandbox Code Playgroud)
public class MyComboBox : ComboBox
{
    private const UInt32 WM_CTLCOLORLISTBOX = 0x0134;
    private const int SWP_NOSIZE = 0x1;
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
        int X, int Y, int cx, int cy, uint uFlags);
    public enum DropDownAlignments { Left = 0, Middle, Right }
    public bool AutoWidthDropDown { get; set; }
    public DropDownAlignments DropDownAlignment { get; set; }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_CTLCOLORLISTBOX)  {
            var bottomLeft = this.PointToScreen(new Point(0, Height));
            var x = bottomLeft.X;
            if (DropDownAlignment == MyComboBox.DropDownAlignments.Middle)
                x -= (DropDownWidth - Width) / 2;
            else if (DropDownAlignment == DropDownAlignments.Right)
                x -= (DropDownWidth - Width);
            var y = bottomLeft.Y;
            SetWindowPos(m.LParam, IntPtr.Zero, x, y, 0, 0, SWP_NOSIZE);
        }
        base.WndProc(ref m);
    }
    protected override void OnDropDown(EventArgs e)
    {
        if (AutoWidthDropDown)
            DropDownWidth = Items.Cast<Object>().Select(x => GetItemText(x))
                  .Max(x => TextRenderer.MeasureText(x, Font,
                       Size.Empty, TextFormatFlags.Default).Width);
        else
            DropDownWidth = this.Width;
        base.OnDropDown(e);
    }
}
Run Code Online (Sandbox Code Playgroud)