Windows窗体ComboBox下拉位置 [英] Windows Forms ComboBox DropDown Position
问题描述
通常下拉菜单的起始位置与 ComboBox
开始位置,如上图所示。
但是我需要开发 ComboBox
控件,该控件的下拉项很长,中间对齐。我的意思是下拉项的左位置应该比<$ c更靠左$ c> ComboBox 如下图所示。任何帮助将不胜感激。
这是扩展的
实现-具有下拉位置和AutoWith DropDown的组合框
您可以处理 WM_CTLCOLORLISTBOX
消息, lparam
是下拉菜单的句柄,然后您可以使用 SetWindowPos
。
如果 AutoWidthDropDown
为true,您还可以计算最长项目的宽度并将其设置为 DropDownWidth
。
使用系统;
使用System.Drawing;
使用System.Runtime.InteropServices;
使用System.Windows.Forms;
使用System.Linq;
公共类MyComboBox: ComboBox
{
private const UInt32 WM_CTLCOLORLISTBOX = 0x0134;
private const int SWP_NOSIZE = 0x1;
[DllImport( user32.dll)]
静态外部布尔值SetWindowPos(IntPtr hWnd,IntPtr hWndInsertAfter,
int X,int Y,int cx,int cy,uint uFlags);
public enum DropDownAlignments {左= 0,中间,右}
public bool AutoWidthDropDown {get;组; }
public DropDownAlignments DropDownAlignment {get;组; }
受保护的覆盖无效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);
}
受保护的覆盖无效OnDropDown(EventArgs e)
{
if(AutoWidthDropDown)
DropDownWidth = Items.Cast< Object>()。Select(x => ; GetItemText(x))
.Max(x => TextRenderer.MeasureText(x,字体,
Size.Empty,TextFormatFlags.Default).Width);
else
DropDownWidth = this.Width;
base.OnDropDown(e);
}
}
Usually dropdown item start position aligned with ComboBox
start position like the image above.
But i need to develop ComboBox
Control which has the lengthy dropdown item gets aligned in middle.I mean Dropdown item left position should still more left positioned than ComboBox
like the image below. Any help would be greatly appreciated.
Here is an extended ComboBox
which have 2 new useful features to let you set the position and size of drop-down:
DropDownAlignment
: You can set it toLeft
, then the drop-down will appear in it's normal position and it's left is aligned with left of control. If you set it toMiddle
, the middle of drop-down will be aligned with control and if you set it toRight
, the right of drop-down will be aligned with right of control.AutoWidthDropDown
: If you set it totrue
to, thenDropdownWidth
will be set to the width of the longest item. If you set it tofalse
it usesWidth
asDropDownWidth
.
Here is appearance of drop-down after setting AutoWidthDropDown
to true
and DropDownAlignment
to Left
, Middle
and Right
:
Implementation - ComboBox with DropDown Position and AutoWith DropDown
You can handle WM_CTLCOLORLISTBOX
message, the lparam
is the handle of drop-down and then you can set position of drop-down using SetWindowPos
.
Also you can calculate width of longest item and set as DropDownWidth
if AutoWidthDropDown
is true.
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);
}
}
这篇关于Windows窗体ComboBox下拉位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!