Windows 表单组合框下拉位置
Windows Forms ComboBox DropDown Position
通常下拉项的起始位置与 ComboBox
起始位置对齐,如上图所示。
但是我需要开发 ComboBox
控件,它有较长的下拉项在 middle.I 中对齐,这意味着下拉项的左侧位置应该比 ComboBox
更靠左,如下图所示。任何帮助将不胜感激。
这是一个扩展的 ComboBox
,它有 2 个有用的新功能,可让您设置下拉菜单的位置和大小:
DropDownAlignment
:你可以设置为Left
,那么下拉框会出现在它的正常位置,它的左边与控件的左边对齐。如果设置为Middle
,下拉框的中间将与控件对齐,如果设置为Right
,下拉框的右侧将与控件的右侧对齐。
AutoWidthDropDown
:如果将其设置为true
,则DropdownWidth
将设置为最长项目的宽度。如果将其设置为 false
,它会将 Width
用作 DropDownWidth
。
下面是将AutoWidthDropDown
设置为true
和DropDownAlignment
设置为Left
、Middle
和Right
后下拉菜单的外观:
实施 - 带有下拉位置和 AutoWith DropDown 的组合框
你可以处理 WM_CTLCOLORLISTBOX
message, the lparam
is the handle of drop-down and then you can set position of drop-down using SetWindowPos
.
如果 AutoWidthDropDown
为真,您还可以计算最长项目的宽度并设置为 DropDownWidth
。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
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);
}
}
通常下拉项的起始位置与 ComboBox
起始位置对齐,如上图所示。
但是我需要开发 ComboBox
控件,它有较长的下拉项在 middle.I 中对齐,这意味着下拉项的左侧位置应该比 ComboBox
更靠左,如下图所示。任何帮助将不胜感激。
这是一个扩展的 ComboBox
,它有 2 个有用的新功能,可让您设置下拉菜单的位置和大小:
DropDownAlignment
:你可以设置为Left
,那么下拉框会出现在它的正常位置,它的左边与控件的左边对齐。如果设置为Middle
,下拉框的中间将与控件对齐,如果设置为Right
,下拉框的右侧将与控件的右侧对齐。AutoWidthDropDown
:如果将其设置为true
,则DropdownWidth
将设置为最长项目的宽度。如果将其设置为false
,它会将Width
用作DropDownWidth
。
下面是将AutoWidthDropDown
设置为true
和DropDownAlignment
设置为Left
、Middle
和Right
后下拉菜单的外观:
实施 - 带有下拉位置和 AutoWith DropDown 的组合框
你可以处理 WM_CTLCOLORLISTBOX
message, the lparam
is the handle of drop-down and then you can set position of drop-down using SetWindowPos
.
如果 AutoWidthDropDown
为真,您还可以计算最长项目的宽度并设置为 DropDownWidth
。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
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);
}
}