我创建了一个ComboBox,当DropDownStyle设置为DropDownList时,它支持在控件上绘制文本。
下面的代码段与代码结构的其余部分不匹配,也没有使用e.States中的正确检查。有谁知道我应该检查哪个e.States?
if (!this.DroppedDown && e.Index == -1)
{
e.Graphics.DrawString(_dropDownListText, e.Font, b, e.Bounds);
}
else if (e.Index > -1)
{
e.Graphics.DrawString(ItemName(e.Index), e.Font, b, e.Bounds);
}
完整的代码,上面的代码段已经注释掉了以便于搜索
using System.ComponentModel;
public class ComboBoxEx : ComboBox
{
private ToolTip _toolTip = new ToolTip();
private string _dropDownListText = "Select...";
public ComboBoxEx()
{
this.DrawMode = DrawMode.OwnerDrawVariable;
this.DropDownStyle = ComboBoxStyle.DropDownList;
}
[Description("Gets or sets the text associated with DropDownList style."), Category("Appearance")]
public string DropDownListText
{
get
{
return _dropDownListText;
}
set
{
if (string.IsNullOrEmpty(value))
{
value = string.Empty;
}
_dropDownListText = value;
}
}
public string ItemName(int index)
{
if (index == -1)
{
return string.Empty;
}
// return the selected item value from the ComboBoxEx.Item class
return ((ComboBoxEx.Item)(this.Items[index])).Name;
}
public string ItemTag(int index)
{
if (index == -1)
{
return string.Empty;
}
// return the selected item tag from the ComboBoxEx.Item class
return ((ComboBoxEx.Item)(this.Items[index])).Tag;
}
protected override void OnSelectedIndexChanged(System.EventArgs e)
{
// force a redraw of DropDownListText if necessary
base.OnSelectedIndexChanged(e);
base.Invalidate();
}
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
{
// select the brush to use as the fore color
SolidBrush b = new SolidBrush((this.Enabled ? SystemColors.WindowText : SystemColors.GrayText));
if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
{
// fill the focused items rectangle
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Info), e.Bounds);
}
else
{
// fill the rest of the rectangle
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Window), e.Bounds);
}
// for ease of reading, I've commented the code out. This code should use proper if then e.State checks so that I can combine it with the rest of the Else If Then statements
/*
if (!this.DroppedDown && e.Index == -1)
{
// redraw the dropdownlist text when the combobox is closed with no index selected
e.Graphics.DrawString(_dropDownListText, e.Font, b, e.Bounds);
}
else if (e.Index > -1)
{
// else, draw the selected item value
e.Graphics.DrawString(ItemName(e.Index), e.Font, b, e.Bounds);
}
*/
if (e.State == (DrawItemState.Disabled | DrawItemState.NoAccelerator | DrawItemState.NoFocusRect | DrawItemState.ComboBoxEdit))
{
// redraw the dropdownlist text when the control is disabled
e.Graphics.DrawString(_dropDownListText, e.Font, b, 3, 3);
}
else if (e.State == (DrawItemState.NoAccelerator | DrawItemState.NoFocusRect | DrawItemState.ComboBoxEdit) && e.Index == -1)
{
// redraw the dropdownlist text when the control is dropped down with no index selected
e.Graphics.DrawString(_dropDownListText, e.Font, b, 3, 3);
}
else if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
if (e.Index > -1 && this.DroppedDown)
{
// show a tool tip on the right side of the control with the selected item tag
_toolTip.Show(ItemTag(e.Index), this, e.Bounds.Right, e.Bounds.Bottom + 5);
}
else
{
// hide the tool tip when the control is no longer dropped down
_toolTip.Hide(this);
}
}
e.DrawFocusRectangle();
b.Dispose();
}
public class Item : object
{
protected string _name;
protected string _tag;
public Item(string name, string tag)
{
_name = name;
_tag = tag;
}
public string Name
{
get
{
return _name;
}
}
public string Tag
{
get
{
return _tag;
}
}
}
}
使用示例:
ComboBoxEx1.Items.Add(new ComboBoxEx.Item("Marks Number", "1-555-555-1000"));
ComboBoxEx1.Items.Add(new ComboBoxEx.Item("Jacks Number", "1-555-555-1001"));
ComboBoxEx1.Items.Add(new ComboBoxEx.Item("Daves Number", "1-555-555-1002"));
ComboBoxEx1.Items.Add(new ComboBoxEx.Item("Joses Number", "1-555-555-1003"));
随意使用此代码供您自己使用。