📄 textcombobox.cs
字号:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using UtilityLibrary.General;
using UtilityLibrary.Win32;
namespace UtilityLibrary.WinControls
{
/// <summary>
/// Summary description for TextComboBox.
/// </summary>
[ToolboxItem(false)]
public class TextComboBox : ComboBoxBase
{
#region Constructors
// For use when hosted by a toolbar
public TextComboBox(bool toolBarUse) : base(toolBarUse)
{
// Override parent, we don't want to do all the painting ourselves
// since we want to let the edit control deal with the text for editing
// the parent class ComboBoxBase knows to do the right stuff with
// non-editable comboboxes as well as editable comboboxes as long
// as we change these flags below
SetStyle(ControlStyles.AllPaintingInWmPaint
|ControlStyles.UserPaint|ControlStyles.Opaque, false);
}
public TextComboBox()
{
// Override parent, we don't want to do all the painting ourselves
// since we want to let the edit control deal with the text for editing
// the parent class ComboBoxBase knows to do the right stuff with
// non-editable comboboxes as well as editable comboboxes as long
// as we change these flags below
SetStyle(ControlStyles.AllPaintingInWmPaint
|ControlStyles.UserPaint|ControlStyles.Opaque, false);
}
#endregion
#region Overrides
protected override void DrawComboBoxItem(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// Call base class to do the "Flat ComboBox" drawing
base.DrawComboBoxItem(g, bounds, Index, selected, editSel);
if ( Index != -1)
{
SolidBrush brush;
brush = new SolidBrush(SystemColors.MenuText);
Size textSize = TextUtil.GetTextSize(g, Items[Index].ToString(), Font);
int top = bounds.Top + (bounds.Height - textSize.Height)/2;
// Check if the combobox is bound to a Data Source
if ( DataSource != null)
DrawDataBoundMember(g, brush, Index, new Point(bounds.Left + 1, top));
else
g.DrawString(Items[Index].ToString(), Font, brush, new Point(bounds.Left + 1, top));
brush.Dispose();
}
}
protected override void DrawComboBoxItemEx(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// This "hack" is necessary to avoid a clipping bug that comes from the fact that sometimes
// we are drawing using the Graphics object for the edit control in the combobox and sometimes
// we are using the graphics object for the combobox itself. If we use the same function to do our custom
// drawing it is hard to adjust for the clipping because of what was said about
base.DrawComboBoxItemEx(g, bounds, Index, selected, editSel);
if ( Index != -1)
{
SolidBrush brush;
brush = new SolidBrush(SystemColors.MenuText);
Size textSize = TextUtil.GetTextSize(g, Items[Index].ToString(), Font);
int top = bounds.Top + (bounds.Height - textSize.Height)/2;
// Clipping rectangle
Rectangle clipRect = new Rectangle(bounds.Left + 4, top, bounds.Width - ARROW_WIDTH - 4, top+textSize.Height);
g.DrawString(Items[Index].ToString(), Font, brush, clipRect);
brush.Dispose();
}
}
protected override void DrawDisableState()
{
// Draw the combobox state disable
base.DrawDisableState();
// Draw the specific disable state to
// this derive class
int index = SelectedIndex;
if ( index == -1 ) return;
using ( Graphics g = CreateGraphics() )
{
using ( Brush b = new SolidBrush(SystemColors.ControlDark) )
{
Rectangle rc = ClientRectangle;
Size textSize = TextUtil.GetTextSize(g, Items[index].ToString(), Font);
// Clipping rectangle
int top = rc.Top + (rc.Height - textSize.Height)/2;
Rectangle clipRect = new Rectangle(rc.Left + 4,
top, rc.Width - 4 - ARROW_WIDTH - 4, top+textSize.Height);
g.DrawString(Items[index].ToString(), Font, b, clipRect);
}
}
}
protected void DrawDataBoundMember(Graphics g, Brush brush, int index, Point point)
{
string text = string.Empty;
if ( DataSource != null )
{
IList list = null;
// We coud be bound to an array list which implement the IList interface
// or we could be bound to a DataSet which implements the IListSource from which
// we can get the IList interface
if ( DataSource is IList)
{
// Assume this is an array object and try to get the data based
// on this assumption
list = (IList)DataSource;
Debug.Assert(list != null, "ComboBox is bound to unrecognized DataSource");
// Now extract the actual text to be displayed
object o = list[index];
Type objectType = o.GetType();
// Now invoke the method that is associate with the
// Display name property of the ComboBox
PropertyInfo pi = objectType.GetProperty(DisplayMember);
text = (string)pi.GetValue(o, null);
}
else
{
// Data set object
if ( DataSource is IListSource )
{
IListSource ls = (IListSource)DataSource;
list = ls.GetList();
Debug.Assert(list != null, "ComboBox is bound to unrecognized DataSource");
// This is a data set object, get the value under that assumption
DataRowView dataRowView = (DataRowView)list[index];
DataRow dataRow = dataRowView.Row;
object o = dataRow[DisplayMember];
text = o.ToString();
}
}
g.DrawString(text, Font, brush, point);
}
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -