This commit is contained in:
2008-03-03 15:21:15 +00:00
parent 63fd25601e
commit bf25814d5b
14 changed files with 1290 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
namespace AT.STO.UI.Win
{
partial class DropDownPanel
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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.combo = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// combo
//
this.combo.DropDownHeight = 1;
this.combo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.combo.FormattingEnabled = true;
this.combo.IntegralHeight = false;
this.combo.Location = new System.Drawing.Point(0, 0);
this.combo.Name = "combo";
this.combo.Size = new System.Drawing.Size(86, 21);
this.combo.TabIndex = 0;
this.combo.DropDown += new System.EventHandler(this.Combo_DropDown);
//
// DropDownPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.combo);
this.Name = "DropDownPanel";
this.Size = new System.Drawing.Size(105, 32);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox combo;
}
}

View File

@@ -0,0 +1,287 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace AT.STO.UI.Win
{
/// <summary>
/// Control that allows any other control that implements IDropDownAware to be displayed
/// in it's own combo-like dropdown area. This Control tries to mimic the standard ComboBox
/// as accurately as possible.
/// </summary>
public partial class DropDownPanel : UserControl, IDropDownAware
{
#region Private Variable Declarations
private IDropDownAware _dropDownControl = null;
private DropDownWindowHelper _dropDownHelper = null;
private Form _owner = null;
#endregion
#region Constructor / Destructor
/// <summary>
/// Default constructor
/// </summary>
public DropDownPanel()
{
InitializeComponent();
_dropDownHelper = new DropDownWindowHelper();
_dropDownHelper.DropDownClosed += new DropDownClosedEventHandler(DropDownHelper_DropDownClosed);
_dropDownHelper.DropDownCancel += new DropDownCancelEventHandler(DropDownHelper_DropDownCancel);
combo.DisplayMember = "Text";
combo.ValueMember = "Id";
}
#endregion
#region Control Events
/// <summary>
/// The owning form is set within this event, wich is required to
/// force the owning form not to loose focus when the dropdown is
/// being displayed. Inherited controls should provide the PopupControl
/// within an overridden implementation of this event.
/// </summary>
/// <param name="e"></param>
protected override void OnHandleCreated(EventArgs e)
{
_owner = this.FindForm();
_dropDownHelper.ReleaseHandle();
if (_owner != null)
{
_dropDownHelper.AssignHandle(_owner.Handle);
}
}
/// <summary>
/// Make sure that the overall control's height is exactly the height
/// of the internal ComboBox and that the ComboBox's widt is exactly the
/// width of the control.
/// </summary>
/// <param name="e"></param>
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
combo.Location = new Point(0, 0);
combo.Width = this.ClientRectangle.Width;
this.Height = combo.Height;
}
#endregion
#region Event Handler
/// <summary>
/// We make our DropDownForm host the choosen control and show it instead
/// of the dropdown portion of the ComboBox.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Combo_DropDown(object sender, EventArgs e)
{
if (!_dropDownHelper.DropDownShowing)
{
DropDownForm dropDown = new DropDownForm(_dropDownControl);
dropDown.FinishEditing += new DropDownValueChangedEventHandler(DropDown_FinishEditing);
dropDown.ValueChanged += new DropDownValueChangedEventHandler(DropDown_ValueChanged);
combo.DroppedDown = false;
dropDown.Width = combo.Width; // KBR ADDED 2/15/08
_dropDownHelper.ShowDropDown(_owner, dropDown, GetDropDownPosition(dropDown));
}
else
{
_dropDownHelper.CloseDropDown();
this.Focus();
}
}
private void DropDownHelper_DropDownClosed(object sender, DropDownClosedEventArgs e)
{
IDropDownAware dropDown = (e.DropDown as IDropDownAware);
if ((dropDown != null) && (dropDown.Value != null))
{
dropDown.FinishEditing -= new DropDownValueChangedEventHandler(DropDown_FinishEditing);
dropDown.ValueChanged -= new DropDownValueChangedEventHandler(DropDown_ValueChanged);
}
combo.DroppedDown = false;
}
private void DropDownHelper_DropDownCancel(object sender, DropDownCancelEventArgs e)
{
if (this.Bounds.Contains(Parent.PointToClient(e.CursorLocation)))
{
e.Cancel = true;
}
else
{
IDropDownAware dropDown = (e.DropDown as IDropDownAware);
if (dropDown != null)
{
dropDown.FinishEditing -= new DropDownValueChangedEventHandler(DropDown_FinishEditing);
dropDown.ValueChanged -= new DropDownValueChangedEventHandler(DropDown_ValueChanged);
}
}
}
private void DropDown_FinishEditing(object sender, DropDownValueChangedEventArgs e)
{
if (e.Value != null)
{
SetValue<long>(e.Value as ILookupItem<long>);
}
if (this.FinishEditing != null)
{
this.FinishEditing(this, e);
}
_dropDownControl.FinishEditing -= new DropDownValueChangedEventHandler(DropDown_FinishEditing);
_dropDownControl.ValueChanged -= new DropDownValueChangedEventHandler(DropDown_ValueChanged);
_dropDownHelper.CloseDropDown();
}
private void DropDown_ValueChanged(object sender, DropDownValueChangedEventArgs e)
{
if (this.ValueChanged != null)
{
this.ValueChanged(this, e);
}
}
#endregion
#region Public Properties
/// <summary>
/// Get or set the control (has to implement IDropDownAware) that is to
/// be displayed as the dropdown portion of the combobox.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IDropDownAware DropDownControl
{
get { return _dropDownControl; }
set
{
_dropDownControl = value;
this.Controls.Add(_dropDownControl as Control);
}
}
#endregion
#region Public Methods
public override string ToString()
{
return this.Name;
}
#endregion
#region Private Methods
/// <summary>
/// Calculate an acceptable position of the DropDownForm even in a
/// multi screen environment.
/// </summary>
/// <param name="DropDown"></param>
/// <returns></returns>
private Point GetDropDownPosition(DropDownForm DropDown)
{
Point lt = Parent.PointToScreen(new Point(Left, Top));
Point rb = Parent.PointToScreen(new Point(Right, Bottom));
Rectangle screen = Screen.FromControl(this).Bounds;
Point point = new Point();
if (((lt.X + DropDown.Width) > (screen.X + screen.Width)) && ((rb.X - DropDown.Width) >= screen.X))
{
point.X = rb.X - DropDown.Width;
if ((point.X + DropDown.Width) > (screen.X + screen.Width))
{
point.X = ((screen.X + screen.Width) - DropDown.Width);
}
}
else
{
point.X = lt.X;
if (point.X < screen.X)
{
point.X = screen.X;
}
}
if (((rb.Y + DropDown.Height) > (screen.Y + screen.Height)) && ((lt.Y - DropDown.Height) >= screen.Y))
{
point.Y = lt.Y - DropDown.Height;
if (point.Y < screen.Y)
{
point.Y = screen.Y;
}
}
else
{
point.Y = rb.Y;
if ((point.Y + DropDown.Height) > (screen.Y + screen.Height))
{
point.Y = ((screen.Y + screen.Height) - DropDown.Height);
}
}
return point;
}
/// <summary>
/// In this implementation we don't the user to edit the ComboBox
/// directly, so we add the new value to the item collection after
/// clearing it first.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Value"></param>
private void SetValue<T>(ILookupItem<T> Value) where T: struct
{
if (DropDownControl != null)
{
ILookupItem<T>[] arr = new ILookupItem<T>[0];
combo.DataSource = arr;
if ((Value != null) && (Value is ILookupItem<long>))
{
DropDownControl.Value = Value;
arr = new ILookupItem<T>[1]{(ILookupItem<T>) Value};
combo.DataSource = arr;
combo.SelectedIndex = 0;
combo.Focus();
}
else
{
DropDownControl.Value = null;
}
}
}
#endregion
#region IDropDownAware Implementation
/// <summary>
/// Fired either on OK, Cancel or a click outside the control to indicate
/// that the user has finished editing.
/// </summary>
public event DropDownValueChangedEventHandler FinishEditing;
/// <summary>
/// Fired on any change of the controls's value during the editing process.
/// </summary>
public event DropDownValueChangedEventHandler ValueChanged;
/// <summary>
/// Gets or sets the controls' value.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Value
{
get { return _dropDownControl.Value; }
set { SetValue<long>(value as ILookupItem<long>); }
}
#endregion
}
}