combobox 如何让text居中_ComboBox文字垂直居中对齐

这篇博客介绍如何在.NET Framework 1.1中创建一个自定义ComboBox,使其下拉列表项可以自定义绘制,并解决ComboBox文本垂直居中对齐的问题。通过使用OwnerDrawFixed模式,调整ItemHeight和Font,以及重写OnDrawItem和WndProc方法,实现了ComboBox文本在中间左侧对齐。同时,提供了调整Edit部分以实现垂直居中的代码示例。
摘要由CSDN通过智能技术生成

I created the custom combobox on .net framework 1.1, i can custom draw dropdown items, but i can't set or draw the combobox text on Middle Left , combobox text always render top left , but i need text should be render on middle left.

[ToolboxBitmap(typeof(ComboBox))]

public class MenComboBox :ComboBox

{

private Image _image = Image.FromFile("Expand.png");

public MenComboBox()

{

this.DrawMode = DrawMode.OwnerDrawFixed;

this.BackColor = Color.White;

this.ItemHeight = 18;

this.Font = new Font("Arial",12f,FontStyle.Regular);

}

protected override void OnDrawItem(DrawItemEventArgs e)

{

if (!DesignMode)

{

if (e.Index > -1)

{

int textHeight = (int)e.Graphics.MeasureString(this.Items[e.Index].ToString(), e.Font).Height;

Point textPos = new Point(e.Bounds.X + 4, e.Bounds.Y + ((this.ItemHeight - textHeight) / 2));

if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)

{

e.Graphics.FillRectangle(Brushes.Blue, e.Bounds);

e.Graphics.DrawString(this.Items[e.Index].ToString(),e.Font,Brushes.White,textPos);

}

else

{

e.Graphics.FillRectangle(Brushes.White, e.Bounds);

e.Graphics.DrawString(this.Items[e.Index].ToString(),e.Font,Brushes.Black,textPos);

}

}

}

}

protected override void WndProc(ref Message m)

{

base.WndProc(ref m);

if (m.Msg == 0x000F)

{

using (Graphics g = this.CreateGraphics())

{

g.FillRectangle(new SolidBrush(BackColor), this.ClientRectangle);

g.DrawRectangle(Pens.Blue, new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1));

Rectangle rect = new Rectangle(this.Width - 15, 3, 12, this.Height - 6);

g.FillRectangle(new SolidBrush(BackColor), rect);

g.DrawImage(this._image, this.Width - 16, (this.Height - 8) / 2);

g.Dispose();

}

}

}

}

解决方案

In an owner draw ComboBox the text of the Edit part of the control will always be shown at top left, regardless of the height of the ItemHeight.

To position the Edit part vertically in middle, you can find the Edit element using GetComboBoxInfo and then using SetWindowPos set a new position for it to stand vertically in middle of the ComboBox.

You need to reposition it when the control size changes. Also you need to fill the background of ComboBox with a Color.

Here is the code that I used:

using System;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;

public class MyComboBox : ComboBox

{

public MyComboBox()

{

SetStyle(ControlStyles.ResizeRedraw, true);

DrawMode = DrawMode.OwnerDrawFixed;

ItemHeight = 40;

}

[StructLayout(LayoutKind.Sequential)]

public struct RECT

{

public int Left;

public int Top;

public int Right;

public int Bottom;

public int Width { get { return Right - Left; } }

public int Height { get { return Bottom - Top; } }

}

private const int SWP_NOSIZE = 0x0001;

private const int SWP_NOZORDER = 0x0004;

private const int SWP_SHOWWINDOW = 0x0040;

[DllImport("user32.dll", SetLastError = true)]

static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,

int X, int Y, int cx, int cy, int uFlags);

[DllImport("user32.dll")]

public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

[StructLayout(LayoutKind.Sequential)]

public struct COMBOBOXINFO

{

public int cbSize;

public RECT rcItem;

public RECT rcButton;

public int stateButton;

public IntPtr hwndCombo;

public IntPtr hwndEdit;

public IntPtr hwndList;

}

protected override void OnResize(EventArgs e)

{

base.OnResize(e);

SetupEdit();

Invalidate();

}

private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;

protected override void WndProc(ref Message m)

{

if (m.Msg == 0xF)

{

using (var g = this.CreateGraphics())

{

var r = new Rectangle(2, 2,

ClientRectangle.Width - buttonWidth - 2,

ClientRectangle.Height - 4);

g.FillRectangle(Brushes.White, r);

}

}

base.WndProc(ref m);

}

protected override void OnVisibleChanged(EventArgs e)

{

base.OnVisibleChanged(e);

SetupEdit();

}

private void SetupEdit()

{

var info = new COMBOBOXINFO();

info.cbSize = Marshal.SizeOf(info);

GetComboBoxInfo(this.Handle, ref info);

SetWindowPos(info.hwndEdit, IntPtr.Zero, 3,

(this.Height - Font.Height) / 2,

ClientRectangle.Width - buttonWidth - 3,

ClientRectangle.Height - Font.Height - 4,

SWP_NOZORDER);

}

protected override void OnDrawItem(DrawItemEventArgs e)

{

base.OnDrawItem(e);

e.DrawBackground();

var txt = "";

if (e.Index >= 0)

txt = GetItemText(Items[e.Index]);

TextRenderer.DrawText(e.Graphics, txt, Font, e.Bounds,

ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值