📄 comboboxbase.cs
字号:
base.OnSelectedIndexChanged(e);
}
fireOnSelectedIndexChanged = true;
}
#endregion
#region Properties
public bool ToolBarUse
{
set { toolBarUse = value; }
get { return toolBarUse; }
}
#endregion
#region Methods
public void SetFontHeight(int newHeight)
{
FontHeight = newHeight;
}
#endregion
#region Implementation
void PaintComboBoxBackground(Graphics g, Color backColor)
{
Rectangle rc = ClientRectangle;
rc.Inflate(-1, -1);
g.FillRectangle(new SolidBrush(backColor), rc);
}
internal void DrawComboBoxBorder(Graphics g, Color color)
{
// Keep track of what we painted last
if ( color.Equals(ColorUtil.VSNetBorderColor) )
{
highlighted = true;
}
else
{
highlighted = false;
}
Pen pen = new Pen(new SolidBrush(color), 1);
g.DrawRectangle(pen, ClientRectangle.Left, ClientRectangle.Top, ClientRectangle.Width-1, ClientRectangle.Height-1);
// We need to draw an extra "inner" border to erase the ugly 3D look of the combobox
g.DrawRectangle(Pens.White, ClientRectangle.Left+1, ClientRectangle.Top+1,
ClientRectangle.Width-SystemInformation.VerticalScrollBarWidth, ClientRectangle.Height-3);
}
internal void DrawComboBoxArrowNormal(Graphics g, bool disable)
{
int left, top, arrowWidth, height;
CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);
// We are not going to draw the arrow background using the total
// width of the arrow button in the combobox because it is too wide
// and it does not look nice. However, we need to paint over the section
// that correspond to the "original" arrow button dimension to avoid
// clipping or painting problems
Brush stripeColorBrush = new SolidBrush(ColorUtil.VSNetControlColor);
if ( Enabled )
{
int width = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH;
g.FillRectangle(Brushes.White, new Rectangle(left-width, top,
SystemInformation.VerticalScrollBarWidth, height));
}
if ( !disable)
{
// Erase previous selected rectangle first
DrawComboBoxArrowSelected(g, true);
// Now draw the unselected background
g.FillRectangle(stripeColorBrush, left, top, arrowWidth, height);
}
else
{
// Now draw the unselected background
g.FillRectangle(stripeColorBrush, left-1, top-1, arrowWidth+2, height+2);
}
DrawArrowGlyph(g, disable);
}
internal void DrawComboBoxArrowSelected(Graphics g, bool erase)
{
int left, top, arrowWidth, height;
CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);
// We are not going to draw the arrow background using the total
// width of the arrow button in the combobox because it too wide
// and it does not look nice. However, we need to paint over the section
// that correspond to the "original" arrow button dimension to avoid
// clipping or painting problems
if ( Enabled )
{
int width = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH;
g.FillRectangle(Brushes.White, new Rectangle(left-width, top,
SystemInformation.VerticalScrollBarWidth, height));
}
if ( !erase )
{
if (DroppedDown)
{
// If showing the list portion of the combo box, draw the arrow portion background using
// the highlight color with some transparency
// Don't use the graphics object that we get passed because that is associated
// to the edit control of the combobox and we actually want to paint on the combobox area
// and not be clipped only to the edit control client area
Graphics cbg = CreateGraphics();
cbg.FillRectangle(new SolidBrush(ColorUtil.VSNetPressedColor), left-1, top-1, arrowWidth+2, height+2);
cbg.DrawRectangle(new Pen( new SolidBrush(ColorUtil.VSNetBorderColor), 1), left-1, top-1, arrowWidth+2, height+3);
// The DrawArrow won't work with the passed Graphics object since it is the one for
// the edit control and we need to paint on the combobox
DrawArrowGlyph(cbg, false);
cbg.Dispose();
forceUpdate = true;
return;
}
else
{
g.FillRectangle(new SolidBrush(ColorUtil.VSNetSelectionColor), left-1, top-1, arrowWidth+2, height+2);
g.DrawRectangle(new Pen( new SolidBrush(ColorUtil.VSNetBorderColor), 1), left-1, top-2, arrowWidth+2, height+3);
}
}
else
{
g.FillRectangle(Brushes.White, left-1, top-1, arrowWidth+2, height+2);
}
DrawArrowGlyph(g, false);
}
void CalculateArrowBoxCoordinates(out int left, out int top, out int width, out int height)
{
Rectangle rc = ClientRectangle;
width = ARROW_WIDTH;
left = rc.Right - width - 2;
top = rc.Top + 2;
height = rc.Height - 4;
}
void DrawArrowGlyph(Graphics g, bool disable)
{
int left, top, arrowWidth, height;
CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);
// Draw arrow glyph
Point[] pts = new Point[3];
pts[0] = new Point(left + arrowWidth/2 - 2, top + height/2-1);
pts[1] = new Point(left + arrowWidth/2 + 3, top + height/2-1);
pts[2] = new Point(left + arrowWidth/2, (top + height/2-1) + 3);
if ( disable )
{
g.FillPolygon(new SolidBrush(SystemColors.ControlDark), pts);
}
else
{
g.FillPolygon(Brushes.Black, pts);
}
}
void ForcePaint(ref Message m)
{
// Similar code to the OnPaint handler
Graphics g = Graphics.FromHwnd(Handle);
if (Enabled == false)
{
DrawDisableState();
return;
}
Rectangle rc = ClientRectangle;
if ( SelectedIndex == -1 )
if ( Items.Count > 0 )
{
fireOnSelectedIndexChanged = false;
SelectedIndex = 0;
}
DrawComboBoxItemEx( g, rc, SelectedIndex, false, true);
if ( !ContainsFocus )
{
DrawComboBoxBorder(g, SystemColors.Window);
DrawComboBoxArrowNormal(g, false);
}
else
{
DrawComboBoxBorder(g, ColorUtil.VSNetBorderColor);
}
}
internal void ForceUpdate()
{
using ( Graphics g = CreateGraphics())
{
if ( ContainsFocus )
DrawComboBoxArrowSelected(g, false);
}
}
void StartHook()
{
// Mouse hook
WindowsAPI.HookProc mouseHookProc = new WindowsAPI.HookProc(MouseHook);
mouseProcHandle = GCHandle.Alloc(mouseHookProc);
mouseHookHandle = WindowsAPI.SetWindowsHookEx((int)WindowsHookCodes.WH_MOUSE,
mouseHookProc, IntPtr.Zero, WindowsAPI.GetCurrentThreadId());
if ( mouseHookHandle == IntPtr.Zero)
throw new SecurityException();
}
void EndHook()
{
// Unhook
WindowsAPI.UnhookWindowsHookEx(mouseHookHandle);
mouseProcHandle.Free();
mouseHookHandle = IntPtr.Zero;
}
IntPtr MouseHook(int code, IntPtr wparam, IntPtr lparam)
{
MOUSEHOOKSTRUCT mh = (MOUSEHOOKSTRUCT )Marshal.PtrToStructure(lparam, typeof(MOUSEHOOKSTRUCT));
if ( mh.hwnd != Handle && !DroppedDown
&& (wparam == (IntPtr)Msg.WM_LBUTTONDOWN || wparam == (IntPtr)Msg.WM_RBUTTONDOWN)
|| wparam == (IntPtr)Msg.WM_NCLBUTTONDOWN )
{
// Loose focus
WindowsAPI.SetFocus(IntPtr.Zero);
}
else if ( mh.hwnd != Handle && !DroppedDown
&& (wparam == (IntPtr)Msg.WM_LBUTTONUP || wparam == (IntPtr)Msg.WM_RBUTTONUP)
|| wparam == (IntPtr)Msg.WM_NCLBUTTONUP )
{
WindowsAPI.SetFocus(IntPtr.Zero);
}
return WindowsAPI.CallNextHookEx(mouseHookHandle, code, wparam, lparam);
}
protected virtual void DrawDisableState()
{
Graphics g = CreateGraphics();
PaintComboBoxBackground(g, SystemColors.Window);
DrawComboBoxBorder(g, SystemColors.ControlDark);
DrawComboBoxArrowNormal(g, true);
g.Dispose();
}
protected virtual void DrawComboBoxItem(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// Draw the the combo item
using ( Brush b = new SolidBrush(SystemColors.Window) )
{
g.FillRectangle( b, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
}
if ( selected && !editSel)
{
// Draw highlight rectangle
Pen p1 = new Pen(ColorUtil.VSNetBorderColor);
Brush b1 = new SolidBrush(ColorUtil.VSNetSelectionColor);
g.FillRectangle(b1, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
g.DrawRectangle(p1, bounds.Left, bounds.Top, bounds.Width-1, bounds.Height-1);
p1.Dispose();
b1.Dispose();
}
else
{
// Erase highlight rectangle
g.FillRectangle(new SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height);
if ( editSel && ContainsFocus )
{
// Draw higlighted arrow
Debug.WriteLine("Drawing ComboBox Arrow...");
DrawComboBoxArrowSelected(g, false);
}
}
}
protected virtual void DrawComboBoxItemEx(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// This function is only called form the OnPaint handler and the Graphics object passed is the one
// for the combobox itself as opossed to the one for the edit control in the combobox
// doing this allows us to be able to avoid clipping problems with text strings
// Draw the the combo item
bounds.Inflate(-3, -3);
using ( Brush b = new SolidBrush(SystemColors.Window) )
{
g.FillRectangle( b, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
}
if ( selected && !editSel)
{
// Draw highlight rectangle
Pen p1 = new Pen(ColorUtil.VSNetBorderColor);
Brush b1 = new SolidBrush(ColorUtil.VSNetSelectionColor);
g.FillRectangle(b1, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
g.DrawRectangle(p1, bounds.Left, bounds.Top, bounds.Width-1, bounds.Height-1);
p1.Dispose();
b1.Dispose();
}
else
{
// Erase highlight rectangle
g.FillRectangle(new SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height);
if ( editSel && ContainsFocus )
{
// Draw higlighted arrow
DrawComboBoxArrowSelected(g, false);
}
}
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -