using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar.SuperGrid.Style;
namespace DevComponents.DotNetBar.SuperGrid
{
///
/// GridComboBoxExEditControl
///
[ToolboxItem(false)]
public class GridComboBoxExEditControl : ComboBoxEx, IGridCellEditControl
{
#region DllImports
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern void GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
#endregion
#region Static data
static bool _StaticIsOpen;
#endregion
#region Private variables
private GridCell _Cell;
private EditorPanel _EditorPanel;
private Bitmap _EditorCellBitmap;
private bool _ValueChanged;
private bool _SuspendUpdate;
private bool _PanelShown;
private bool _CacheDisplayMembers = true;
private int _ValueIndex;
private string _ValueText;
private int[] _ValueIndicees;
private object[] _ValueMembers;
private CurrencyManager _CurrentDataManager;
private StretchBehavior _StretchBehavior = StretchBehavior.None;
#endregion
///
/// GridComboBoxExEditControl
///
public GridComboBoxExEditControl()
{
DrawMode = DrawMode.OwnerDrawFixed;
DisconnectedPopupDataSource = true;
BindingContext = new BindingContext();
}
#region OnDataSourceChanged
///
/// OnDataSourceChanged
///
///
protected override void OnDataSourceChanged(EventArgs e)
{
if (_CurrentDataManager != null)
_CurrentDataManager.ListChanged -= DataManagerListChanged;
base.OnDataSourceChanged(e);
_ValueMembers = null;
_ValueIndicees = null;
_CurrentDataManager = DataManager;
if (_CurrentDataManager != null)
_CurrentDataManager.ListChanged += DataManagerListChanged;
if (IsDisposed == false)
{
if (_Cell != null && _Cell.GridPanel != null)
InitializeContext(_Cell, null);
}
}
#endregion
#region DataManagerListChanged
///
/// DataManager_ListChanged
///
///
///
void DataManagerListChanged(object sender, ListChangedEventArgs e)
{
_ValueMembers = null;
_ValueIndicees = null;
}
#endregion
#region OnTextChanged
///
/// OnTextChanged
///
///
protected override void OnTextChanged(EventArgs e)
{
if (IsDisposed == false)
{
if (_Cell != null && _SuspendUpdate == false)
{
_Cell.EditorValueChanged(this);
_ValueIndex = -1;
}
}
base.OnTextChanged(e);
}
#endregion
#region OnSelectedIndexChanged
///
/// OnSelectedIndexChanged
///
///
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (IsDisposed == false)
{
if (_Cell != null && _SuspendUpdate == false)
{
_ValueIndex = SelectedIndex;
_Cell.EditorValueChanged(this);
EditorValueChanged = true;
}
}
base.OnSelectedIndexChanged(e);
}
#endregion
#region OnInvalidated
///
/// OnInvalidated
///
///
protected override void OnInvalidated(InvalidateEventArgs e)
{
base.OnInvalidated(e);
if (_Cell != null && _SuspendUpdate == false)
_Cell.InvalidateRender();
}
#endregion
#region GetValue
///
/// GetValue
///
///
///
public virtual object GetValue(object value)
{
GridPanel panel = _Cell.GridPanel;
if (value == null ||
(panel.NullValue == NullValue.DBNull && value == DBNull.Value))
{
return ("");
}
if (_Cell.IsValueExpression == true)
value = _Cell.GetExpValue((string)value);
return (value);
}
#endregion
#region SetValue
private void SetValue(object o, bool initEdit)
{
_ValueText = "";
_ValueIndex = -1;
bool oldSuspend = SuspendUpdate;
SuspendUpdate = true;
SelectedIndex = -1;
SuspendUpdate = oldSuspend;
if (o != null)
{
_ValueText = o.ToString();
if (string.IsNullOrEmpty(_ValueText) == false &&
string.IsNullOrEmpty(ValueMember) == false &&
string.IsNullOrEmpty(DisplayMember) == false)
{
if (Items.Count > 0)
{
if (Items[0] is DataRowView &&
initEdit == false && _CacheDisplayMembers == true)
{
SetSelectedDrvValue(o);
}
else
{
SetSelectedValue(o);
}
}
}
else
{
Text = _ValueText;
_ValueIndex = SelectedIndex;
}
}
}
#region SetSelectedDrvValue
private void SetSelectedDrvValue(object o)
{
if (_ValueMembers == null)
{
SuspendUpdate = true;
_ValueMembers = new object[Items.Count];
_ValueIndicees = new int[Items.Count];
for (int i = 0; i < Items.Count; i++)
{
DataRowView drv = (DataRowView)Items[i];
_ValueMembers[i] = drv.Row[ValueMember];
_ValueIndicees[i] = i;
}
Array.Sort(_ValueMembers, _ValueIndicees);
SuspendUpdate = false;
}
int n = -1;
try
{
n = Array.BinarySearch(_ValueMembers, o);
}
catch { }
if (n >= 0)
{
_ValueIndex = _ValueIndicees[n];
_ValueText = GetItemText(Items[_ValueIndex]);
}
else
{
Text = _ValueText;
}
}
#endregion
#region SetSelectedValue
private void SetSelectedValue(object o)
{
try
{
SelectedValue = o;
_ValueIndex = SelectedIndex;
if (SelectedValue != null)
_ValueText = Text;
}
catch
{
Text = _ValueText;
}
}
#endregion
#endregion
#region IGridCellEditControl Members
#region Public properties
#region CacheDisplayMembers
///
/// Informs the control to cache DataRowView
/// ValueMember/DisplayMember information (default is true).
///
public bool CacheDisplayMembers
{
get { return (_CacheDisplayMembers); }
set
{
_CacheDisplayMembers = value;
if (value == false)
{
_ValueMembers = null;
_ValueIndicees = null;
}
}
}
#endregion
#region CanInterrupt
///
/// CanInterrupt
///
public virtual bool CanInterrupt
{
get { return (true); }
}
#endregion
#region CellEditMode
CellEditMode _CellEditMode = CellEditMode.Modal;
///
/// CellEditMode
///
public virtual CellEditMode CellEditMode
{
get { return (_CellEditMode); }
}
#endregion
#region EditorCell
///
/// EditorCell
///
public GridCell EditorCell
{
get { return (_Cell); }
set { _Cell = value; }
}
#endregion
#region EditorCellBitmap
///
/// EditorCellBitmap
///
public Bitmap EditorCellBitmap
{
get { return (_EditorCellBitmap); }
set
{
if (_EditorCellBitmap != null)
_EditorCellBitmap.Dispose();
_EditorCellBitmap = value;
}
}
#endregion
#region EditorFormattedValue
///
/// EditorFormattedValue
///
public virtual string EditorFormattedValue
{
get
{
if (_Cell != null && _Cell.IsValueNull == true)
return (_Cell.NullString);
return (_ValueText);
}
}
#endregion
#region EditorPanel
///
/// EditorPanel
///
public EditorPanel EditorPanel
{
get { return (_EditorPanel); }
set { _EditorPanel = value; }
}
#endregion
#region EditorValue
///
/// EditorValue
///
public virtual object EditorValue
{
get
{
if (_ValueIndex >= 0)
SelectedIndex = _ValueIndex;
if (string.IsNullOrEmpty(ValueMember) == false)
return (SelectedValue ?? Text);
if (string.IsNullOrEmpty(DisplayMember) == false)
return (Text);
return (this.SelectedValue ?? this.SelectedItem ?? Text);
}
set { SetValue(GetValue(value), true); }
}
#endregion
#region EditorValueChanged
///
/// EditorValueChanged
///
public virtual bool EditorValueChanged
{
get { return (_ValueChanged); }
set
{
if (_ValueChanged != value)
{
_ValueChanged = value;
if (value == true)
_Cell.SetEditorDirty(this);
}
}
}
#endregion
#region EditorValueType
///
/// EditorValueType
///
public virtual Type EditorValueType
{
get { return (typeof(string)); }
}
#endregion
#region StretchBehavior
///
/// StretchBehavior
///
public virtual StretchBehavior StretchBehavior
{
get { return (_StretchBehavior); }
set { _StretchBehavior = value; }
}
#endregion
#region SuspendUpdate
///
/// SuspendUpdate
///
public bool SuspendUpdate
{
get { return (_SuspendUpdate); }
set { _SuspendUpdate = value; }
}
#endregion
#region ValueChangeBehavior
///
/// ValueChangeBehavior
///
public virtual ValueChangeBehavior ValueChangeBehavior
{
get { return (ValueChangeBehavior.InvalidateRender); }
}
#endregion
#endregion
#region InitializeContext
///
/// InitializeContext
///
///
///
public virtual void InitializeContext(GridCell cell, CellVisualStyle style)
{
_Cell = cell;
if (style != null)
{
Enabled = (_Cell.ReadOnly == false);
Font = style.Font;
ForeColor = style.TextColor;
}
SetValue(GetValue(_Cell.Value), false);
_ValueChanged = false;
}
#endregion
#region GetProposedSize
///
/// GetProposedSize
///
///
///
///
///
///
public virtual Size GetProposedSize(Graphics g,
GridCell cell, CellVisualStyle style, Size constraintSize)
{
eTextFormat tf = eTextFormat.NoClipping |
eTextFormat.WordEllipsis | eTextFormat.NoPrefix;
if (style.AllowWrap == Tbool.True)
tf |= eTextFormat.WordBreak;
string s = EditorFormattedValue;
if (String.IsNullOrEmpty(s) == true)
s = " ";
Size size = (constraintSize.IsEmpty == true)
? TextHelper.MeasureText(g, s, style.Font)
: TextHelper.MeasureText(g, s, style.Font, constraintSize, tf);
if (ItemHeight > size.Height)
size.Height = ItemHeight;
size.Height += Dpi.Height(DefaultMargin.Vertical);
return (size);
}
#endregion
#region Edit support
#region BeginEdit
///
/// BeginEdit
///
///
///
public virtual bool BeginEdit(bool selectAll)
{
// If we are caching Display/Value member info, then
// force the ComboBox to now set the correct SelectedValue.
if (CacheDisplayMembers == true)
{
object o = EditorValue;
}
return (false);
}
#endregion
#region EndEdit
///
/// EndEdit
///
///
public virtual bool EndEdit()
{
if (IsPopupOpen == true)
IsPopupOpen = false;
return (false);
}
#endregion
#region CancelEdit
///
/// CancelEdit
///
///
public virtual bool CancelEdit()
{
if (IsPopupOpen == true)
IsPopupOpen = false;
return (false);
}
#endregion
#endregion
#region CellRender
///
/// CellRender
///
///
public virtual void CellRender(Graphics g)
{
if (_PanelShown == false)
{
_EditorPanel.Show();
_EditorPanel.Hide();
_PanelShown = true;
}
_Cell.CellRender(this, g);
}
#endregion
#region Keyboard support
#region CellKeyDown
///
/// CellKeyDown
///
public virtual void CellKeyDown(KeyEventArgs e)
{
Focus();
switch (e.KeyData)
{
default:
OnKeyDown(e);
break;
}
}
#endregion
#region WantsInputKey
///
/// WantsInputKey
///
///
///
///
public virtual bool WantsInputKey(Keys key, bool gridWantsKey)
{
switch (key & Keys.KeyCode)
{
case Keys.Space:
case Keys.Up:
case Keys.Down:
return (true);
case Keys.Enter:
if (DroppedDown == true || IsPopupOpen == true)
return (true);
if (AutoCompleteMode != AutoCompleteMode.None)
{
if (string.IsNullOrEmpty(DropDownColumns) == true)
{
if (IsAutoSuggestOpen() == true)
return (true);
}
}
break;
}
return (gridWantsKey == false);
}
#region IsAutoSuggestOpen
private bool IsAutoSuggestOpen()
{
_StaticIsOpen = false;
EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowCallback, IntPtr.Zero);
return (_StaticIsOpen);
}
#region EnumThreadWindowCallback
private static bool EnumThreadWindowCallback(IntPtr hWnd, IntPtr lParam)
{
if (IsWindowVisible(hWnd) == true)
{
if ((GetClassName(hWnd) == "Auto-Suggest Dropdown"))
{
_StaticIsOpen = true;
return (false);
}
}
return true;
}
#region GetClassName
private static string GetClassName(IntPtr hRef)
{
StringBuilder lpClassName = new StringBuilder(256);
GetClassName(hRef, lpClassName, 256);
return (lpClassName.ToString());
}
#endregion
#endregion
#endregion
#endregion
#endregion
#region Mouse support
#region OnCellMouseMove
///
/// OnCellMouseMove
///
///
public virtual void OnCellMouseMove(MouseEventArgs e)
{
}
#endregion
#region OnCellMouseEnter
///
/// OnCellMouseEnter
///
///
public virtual void OnCellMouseEnter(EventArgs e)
{
}
#endregion
#region OnCellMouseLeave
///
/// OnCellMouseLeave
///
///
public virtual void OnCellMouseLeave(EventArgs e)
{
}
#endregion
#region OnCellMouseUp
///
/// OnCellMouseUp
///
///
public virtual void OnCellMouseUp(MouseEventArgs e)
{
}
#endregion
#region OnCellMouseDown
///
/// OnCellMouseDown
///
///
public virtual void OnCellMouseDown(MouseEventArgs e)
{
}
#endregion
#endregion
#endregion
#region Dispose
///
/// Dispose
///
///
protected override void Dispose(bool disposing)
{
if (_CurrentDataManager != null)
_CurrentDataManager.ListChanged -= DataManagerListChanged;
BindingContext = null;
base.Dispose(disposing);
}
#endregion
}
}