vbAccelerator - Contents of code file: PopupControl_FormComboBox.csusing System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace PopupControl
{
/// <summary>
/// Implements a control which works like a Windows ComboBox but
/// allows a form to be used as the drop-down.
/// </summary>
public class FormComboBox : System.Windows.Forms.UserControl, IFormComboBox
{
public event EventHandler DropDown;
public event EventHandler CloseUp;
private IFormComboBoxDropDown popup = null;
private bool mouseOver = false;
private bool entered = false;
private bool dropped = false;
private Rectangle dropDownButton = new Rectangle(0, 0, 0, 0);
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public FormComboBox() : base()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
textBox1.MouseEnter += new EventHandler(textBox1_MouseEnter);
textBox1.MouseLeave += new EventHandler(textBox1_MouseLeave);
textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox1.Location = new System.Drawing.Point(0, 4);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(272, 13);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// FormComboBox
//
this.BackColor = System.Drawing.SystemColors.Window;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textBox1});
this.Name = "FormComboBox";
this.Size = new System.Drawing.Size(292, 20);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// Request that the combo box is closed up
/// </summary>
public void RequestCloseUp()
{
if (dropped)
{
OnCloseUp(new EventArgs());
}
}
/// <summary>
/// Request that the selected index is changed
/// </summary>
/// <param name="index">New index to select</param>
public void SelectedIndexChanged(int index)
{
if (this.popup != null)
{
string item = popup.Item(index).ToString();
textBox1.Text = item;
}
}
/// <summary>
/// Gets/sets the Drop-Down form object that will be shown
/// when the combo-box is dropped.
/// </summary>
public IFormComboBoxDropDown DropDownForm
{
get
{
return this.popup;
}
set
{
this.popup = value;
}
}
public new bool Enabled
{
get
{
return base.Enabled;
}
set
{
base.Enabled = value;
if (value)
{
textBox1.BackColor = this.BackColor;
}
else
{
textBox1.BackColor = Color.FromKnownColor(KnownColor.Control);
}
Invalidate();
}
}
/// <summary>
/// Raises the SizeChanged event and sizes the text box within the
control.
/// </summary>
/// <param name="e">Not used</param>
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
int top = 1 + (this.ClientRectangle.Height - textBox1.Height) / 2;
if (this.RightToLeft == RightToLeft.Yes)
{
textBox1.Location = new
Point(SystemInformation.VerticalScrollBarWidth, top);
dropDownButton = new Rectangle(0, 0,
SystemInformation.VerticalScrollBarWidth,
this.ClientRectangle.Height);
}
else
{
textBox1.Location = new Point(2, top);
dropDownButton = new Rectangle(this.ClientRectangle.Width -
SystemInformation.VerticalScrollBarWidth, 0,
SystemInformation.VerticalScrollBarWidth,
this.ClientRectangle.Height);
}
textBox1.Width = this.ClientRectangle.Width -
SystemInformation.VerticalScrollBarWidth - 3;
}
/// <summary>
/// Draws the border and drop-down button in the control and raises
/// the Paint event.
/// </summary>
/// <param name="e">Paint event information</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (this.Enabled)
{
// Draw the border:
if (entered || mouseOver)
{
Rectangle borderRect = new
Rectangle(this.ClientRectangle.Location,
this.ClientRectangle.Size);
borderRect.Width--;
borderRect.Height--;
e.Graphics.DrawRectangle(SystemPens.Highlight, borderRect);
}
// Draw the drop down button:
bool doLine = false;
Rectangle fillRect = new Rectangle(dropDownButton.Location,
dropDownButton.Size);
fillRect.Inflate(-1, -1);
if (dropped)
{
Brush br = new SolidBrush(VSNetPressedColor());
e.Graphics.FillRectangle(br, fillRect);
br.Dispose();
doLine = true;
}
else if (entered || mouseOver)
{
Brush br = new SolidBrush(VSNetSelectionColor());
e.Graphics.FillRectangle(br, fillRect);
br.Dispose();
doLine = true;
}
else
{
e.Graphics.FillRectangle(SystemBrushes.Control, fillRect);
}
if (doLine)
{
if (this.RightToLeft == RightToLeft.Yes)
{
e.Graphics.DrawLine(SystemPens.Highlight, fillRect.Right,
fillRect.Top, fillRect.Right, fillRect.Bottom);
}
else
{
e.Graphics.DrawLine(SystemPens.Highlight, fillRect.Left,
fillRect.Top, fillRect.Left, fillRect.Bottom);
}
}
DrawComboDropDownGlyph(e.Graphics, fillRect,
Color.FromKnownColor(KnownColor.WindowText));
}
else
{
e.Graphics.FillRectangle(SystemBrushes.Control, e.ClipRectangle);
Rectangle borderRect = new Rectangle(this.ClientRectangle.Location,
this.ClientRectangle.Size);
borderRect.Width--;
borderRect.Height--;
e.Graphics.DrawRectangle(SystemPens.ControlDark, borderRect);
DrawComboDropDownGlyph(e.Graphics, dropDownButton,
Color.FromKnownColor(KnownColor.ControlDark));
}
}
/// <summary>
/// Draws a combo-box drop-down glyph in the specified rectangle.
/// </summary>
/// <param name="gfx">Graphics object to draw on</param>
/// <param name="rcButton">Rectangle to centre glyph within</param>
/// <param name="color">Color to draw glyph</param>
private void DrawComboDropDownGlyph(
Graphics gfx,
Rectangle rcButton,
Color color
)
{
int xC = rcButton.X + (rcButton.Width / 2) + 1;
int yC = rcButton.Y + (rcButton.Height / 2) + 1;
Pen pen = new Pen(color, 1);
gfx.DrawLine(pen, xC - 2, yC - 1, xC + 2, yC - 1);
gfx.DrawLine(pen, xC - 1, yC, xC + 1, yC);
gfx.DrawLine(pen, xC, yC - 1, xC, yC + 1);
pen.Dispose();
}
/// <summary>
/// Raises the MouseEnter event and performs highlighting of the control.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
ProcessMouseEnter();
}
private void textBox1_MouseEnter(object sender, EventArgs e)
{
ProcessMouseEnter();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
ProcessMouseLeave();
}
private void textBox1_MouseLeave(object sender, EventArgs e)
{
ProcessMouseLeave();
}
private void ProcessMouseEnter()
{
if (!this.mouseOver)
{
this.mouseOver = true;
Invalidate();
}
}
private void ProcessMouseLeave()
{
Point cursorLocation = Cursor.Position;
cursorLocation = this.PointToClient(cursorLocation);
if (!this.ClientRectangle.Contains(cursorLocation))
{
if (this.mouseOver)
{
this.mouseOver = false;
Invalidate();
}
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Point point = new Point(e.X, e.Y);
if (dropDownButton.Contains(point))
{
if (dropped)
{
OnCloseUp(new EventArgs());
}
else
{
OnDropDown(new EventArgs());
}
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
ProcessKeyEvent(e);
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
ProcessKeyEvent(e);
}
private void ProcessKeyEvent(KeyEventArgs e)
{
if (e.KeyCode == Keys.F4)
{
if (dropped)
{
OnCloseUp(new EventArgs());
}
else
{
OnDropDown(new EventArgs());
}
}
else if (dropped)
{
if (popup != null)
{
popup.KeyDown(e);
}
}
}
protected virtual void OnDropDown(EventArgs e)
{
dropped = true;
if (DropDown != null)
{
DropDown(this, e);
}
if (popup != null)
{
/// TODO: right to left
Point location = new Point(0, this.Bounds.Height);
location = this.PointToScreen(location);
popup.FormComboBox = this;
popup.Show(location);
}
Invalidate();
}
protected virtual void OnCloseUp(EventArgs e)
{
dropped = false;
if (CloseUp != null)
{
CloseUp(this, e);
}
if (popup != null)
{
popup.Hide();
}
Invalidate();
}
protected override void OnEnter(EventArgs e)
{
base.OnEnter(e);
this.entered = true;
Invalidate();
}
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
this.entered = false;
if (this.dropped)
{
OnCloseUp(new EventArgs());
}
else
{
Invalidate();
}
}
private Color BlendColor(
Color colorFrom,
Color colorTo,
int alpha
)
{
return Color.FromArgb(
((colorFrom.R * alpha) / 255) + ((colorTo.R * (255 - alpha)) / 255),
((colorFrom.G * alpha) / 255) + ((colorTo.G * (255 - alpha)) / 255),
((colorFrom.B * alpha) / 255) + ((colorTo.B * (255 - alpha)) / 255)
);
}
private Color VSNetControlColor()
{
return BlendColor(
Color.FromKnownColor(KnownColor.Control),
VSNetBackgroundColor(),
195);
}
private Color VSNetBackgroundColor()
{
return BlendColor(
Color.FromKnownColor(KnownColor.Window),
Color.FromKnownColor(KnownColor.Control),
220);
}
private Color VSNetCheckedColor()
{
return BlendColor(
Color.FromKnownColor(KnownColor.Highlight),
Color.FromKnownColor(KnownColor.Window),
30);
}
private Color VSNetBorderColor()
{
return Color.FromKnownColor(KnownColor.Highlight);
}
private Color VSNetSelectionColor()
{
return BlendColor(
Color.FromKnownColor(KnownColor.Highlight),
Color.FromKnownColor(KnownColor.Window),
70);
}
private Color VSNetPressedColor()
{
return BlendColor(
Color.FromKnownColor(KnownColor.Highlight),
VSNetSelectionColor(),
70);
}
}
/// <summary>
/// The interface that the FormComboBox implements that is
/// provided to a drop-down form attached to the control
/// </summary>
public interface IFormComboBox
{
/// <summary>
/// Request that the combo box is closed up
/// </summary>
void RequestCloseUp();
/// <summary>
/// Request that the selected index is changed
/// </summary>
/// <param name="index">New index to select</param>
void SelectedIndexChanged(int index);
}
/// <summary>
/// The interface that the form shown from the FormComboBox
/// must implement
/// </summary>
public interface IFormComboBoxDropDown
{
/// <summary>
/// Sets the interface to owning form combo box. This interface
/// can be used to modify the selected item and to request that
/// the combo box is closed up.
/// </summary>
IFormComboBox FormComboBox
{
set;
}
/// <summary>
/// Gets the number of items in the drop-down
/// </summary>
int ItemCount
{
get;
}
/// <summary>
/// Gets the item with the specified index
/// </summary>
/// <param name="index">0-based index of item</param>
/// <returns>Item with specified index</returns>
object Item(int index);
/// <summary>
/// Show the drop-down at the specified location.
/// </summary>
/// <param name="location">Point to show form at relative to the
screen</param>
void Show(Point location);
/// <summary>
/// Hide the drop-down if it is shown
/// </summary>
void Hide();
/// <summary>
/// Request to find an object which matches the specified string
/// </summary>
/// <param name="item">String to find</param>
/// <returns>0-based index of item if found, 0 otherwise</returns>
int FindString(String item);
/// <summary>
/// Forwards a key stroke from the control for processing in the
/// drop-down
/// </summary>
/// <param name="e">Key which was pressed</param>
void KeyDown(KeyEventArgs e);
}
}
|
|