如何在C#中为组合框的文本设置图像
how to set image for text of combobox in c#
我正在尝试在自定义控件中的 Combobox 内绘制图像,我使用以下代码:
public partial class Jo_ComboBox : ComboBox
{
#region Constructor
public Jo_ComboBox()
{
InitializeComponent();
}
#endregion
#region Fields
bool _IsRequired = false;
bool _IsEmpty = true;
Bitmap _xImg;
#endregion
#region Properties
[Category("Joul_Properties")]
public Bitmap xImg { get { return _xImg; } }
[Category("Joul_Properties")]
public bool IsEmpty { get { return _IsEmpty; } }
[Category("Joul_Properties")]
public bool IsRequired { get { return _IsRequired; } set { _IsRequired = value; } }
#endregion
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
if (IsRequired == true && this.Text == string.Empty)
{
_xImg = Resources._16Exc;
e.Graphics.DrawImage(xImg, new Point(this.Width - 18, 30));
_IsEmpty = true;
}
else
{
_IsEmpty = false;
}
}
#region Events
//OnLeave
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
this.Invalidate();
}
#endregion
实际上,我得到了一个不错的结果,但我注意到图像不在组合框的文本框上方,我注意到当我尝试更改组合框的高度时。
请查看视频以了解问题所在:
编辑:
如果我改变高度,请看有编辑区域覆盖图像
谢谢@dr.null
我应用了以下代码,它正在运行:
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);
}
}
我正在尝试在自定义控件中的 Combobox 内绘制图像,我使用以下代码:
public partial class Jo_ComboBox : ComboBox
{
#region Constructor
public Jo_ComboBox()
{
InitializeComponent();
}
#endregion
#region Fields
bool _IsRequired = false;
bool _IsEmpty = true;
Bitmap _xImg;
#endregion
#region Properties
[Category("Joul_Properties")]
public Bitmap xImg { get { return _xImg; } }
[Category("Joul_Properties")]
public bool IsEmpty { get { return _IsEmpty; } }
[Category("Joul_Properties")]
public bool IsRequired { get { return _IsRequired; } set { _IsRequired = value; } }
#endregion
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
if (IsRequired == true && this.Text == string.Empty)
{
_xImg = Resources._16Exc;
e.Graphics.DrawImage(xImg, new Point(this.Width - 18, 30));
_IsEmpty = true;
}
else
{
_IsEmpty = false;
}
}
#region Events
//OnLeave
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
this.Invalidate();
}
#endregion
实际上,我得到了一个不错的结果,但我注意到图像不在组合框的文本框上方,我注意到当我尝试更改组合框的高度时。
请查看视频以了解问题所在:
编辑: 如果我改变高度,请看有编辑区域覆盖图像
谢谢@dr.null
我应用了以下代码,它正在运行:
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);
}
}