ext/Aga.Controls/Tree/NodeControls/EditableControl.cs (172 lines of code) (raw):

using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; namespace Aga.Controls.Tree.NodeControls { public abstract class EditableControl : InteractiveControl { private Timer _timer; private bool _editFlag; #region Properties private TreeNodeAdv _editNode; protected TreeNodeAdv EditNode { get { return _editNode; } } private Control _editor; protected Control CurrentEditor { get { return _editor; } } private bool _editOnClick = false; [DefaultValue(false)] public bool EditOnClick { get { return _editOnClick; } set { _editOnClick = value; } } #endregion protected EditableControl() { _timer = new Timer(); _timer.Interval = 500; _timer.Tick += new EventHandler(TimerTick); } private void TimerTick(object sender, EventArgs e) { _timer.Stop(); if (_editFlag) BeginEditByUser(); _editFlag = false; } public void SetEditorBounds(EditorContext context) { Size size = CalculateEditorSize(context); context.Editor.Bounds = new Rectangle(context.Bounds.X, context.Bounds.Y, Math.Min(size.Width, context.Bounds.Width), context.Bounds.Height); } protected abstract Size CalculateEditorSize(EditorContext context); protected virtual bool CanEdit(TreeNodeAdv node) { return (node.Tag != null) && IsEditEnabled(node); } protected void BeginEditByUser() { if (EditEnabled) BeginEdit(); } public void BeginEdit() { if (Parent.CurrentNode != null && CanEdit(Parent.CurrentNode)) { CancelEventArgs args = new CancelEventArgs(); OnEditorShowing(args); if (!args.Cancel) { Control editor = CreateEditor(Parent.CurrentNode); if (null != editor) { _editor = editor; _editor.Validating += new CancelEventHandler(EditorValidating); _editor.KeyDown += new KeyEventHandler(EditorKeyDown); _editNode = Parent.CurrentNode; Parent.DisplayEditor(_editor, this); } } } } // !!! changed by mzinner@mysql.com // ml: act only for key input if the event wasn't handled already. protected virtual void EditorKeyDown(object sender, KeyEventArgs e) { if (!e.Handled) { if (e.KeyCode == Keys.Escape) EndEdit(false); else if (e.KeyCode == Keys.Enter) EndEdit(true); } } private void EditorValidating(object sender, CancelEventArgs e) { ApplyChanges(); } internal void HideEditor(Control editor) { editor.Validating -= EditorValidating; editor.Parent = null; editor.Dispose(); _editNode = null; _editor = null; OnEditorHidden(); } public void EndEdit(bool applyChanges) { if (!applyChanges && _editor != null) _editor.Validating -= EditorValidating; Parent.Focus(); Parent.Cursor = Cursors.Default; Cursor.Show(); } public virtual void UpdateEditor(Control control) { } public virtual void ApplyChanges() { try { DoApplyChanges(_editNode, _editor); } catch (ArgumentException ex) { MessageBox.Show(ex.Message, "Value is not valid", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } protected abstract void DoApplyChanges(TreeNodeAdv node, Control editor); protected abstract Control CreateEditor(TreeNodeAdv node); public override void MouseDown(TreeNodeAdvMouseEventArgs args) { _editFlag = (!EditOnClick && args.Button == MouseButtons.Left && args.ModifierKeys == Keys.None && args.Node.IsSelected); } public override void MouseUp(TreeNodeAdvMouseEventArgs args) { if (EditOnClick && args.Button == MouseButtons.Left && args.ModifierKeys == Keys.None) { if (_editor != null) EndEdit(true); Parent.ItemDragMode = false; BeginEdit(); args.Handled = true; } else if (_editFlag && args.Node.IsSelected) _timer.Start(); } public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args) { _editFlag = false; _timer.Stop(); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) _timer.Dispose(); } #region Events public event CancelEventHandler EditorShowing; protected void OnEditorShowing(CancelEventArgs args) { if (EditorShowing != null) EditorShowing(this, args); } public event EventHandler EditorHided; protected void OnEditorHidden() { if (EditorHided != null) EditorHided(this, EventArgs.Empty); } #endregion } }