/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.Drawing; using System.Windows.Forms; namespace JetBrains.JetListViewLibrary { public interface IInPlaceEditor { void BeginEdit( JetListView jetListView, JetListViewColumn col, JetListViewNode node ); void CloseEdit( bool save ); } internal class InPlaceTextBox: TextBox { protected override bool IsInputKey( Keys keyData ) { if ( keyData == Keys.Escape || keyData == Keys.Enter ) { return true; } return base.IsInputKey( keyData ); } } /// /// Control for in-place editing JetListView2 item values in a text box. /// public class InPlaceTextEditor: IInPlaceEditor { private TextBox _inPlaceEditBox; private Rectangle _inPlaceEditRect; private bool _closingInPlaceEdit = false; private JetListView _host; private JetListViewNode _editNode; private JetListViewColumn _editColumn; private string _startEditText; public InPlaceTextEditor() { _inPlaceEditBox = new InPlaceTextBox(); _inPlaceEditBox.BorderStyle = BorderStyle.FixedSingle; _inPlaceEditBox.Visible = false; _inPlaceEditBox.KeyDown += new KeyEventHandler( HandleInPlaceKeyDown ); _inPlaceEditBox.KeyPress += new KeyPressEventHandler( HandleInPlaceKeyPress ); _inPlaceEditBox.LostFocus += new EventHandler( HandleInPlaceLostFocus ); _inPlaceEditBox.TextChanged += new EventHandler( HandleInPlaceTextChanged ); } /// /// Occurs when the user starts editing the text of an item. /// public event JetItemEditEventHandler BeforeItemEdit; /// /// Occurs when the text of an item is edited by the user. /// public event JetItemEditEventHandler AfterItemEdit; public void BeginEdit( JetListView jetListView, JetListViewColumn col, JetListViewNode node ) { _host = jetListView; _editColumn = col; _editNode = node; if ( !jetListView.Controls.Contains( _inPlaceEditBox ) ) { jetListView.Controls.Add( _inPlaceEditBox ); } Rectangle rc = jetListView.GetItemBounds( node, col ); if ( col.SizeToContent ) { rc.Width = jetListView.InternalClientRect().Width - rc.Left; } JetItemEditEventArgs args = new JetItemEditEventArgs( col.GetItemText( node.Data, rc.Width ), node.Data, col ); OnBeforeItemEdit( args ); if ( args.CancelEdit ) return; jetListView.ScrollInView( node ); jetListView.SetEditedNode( node ); _inPlaceEditRect = new Rectangle( rc.Left-2, rc.Top-1, rc.Width+4, rc.Height+2 ); _inPlaceEditBox.Bounds = _inPlaceEditRect; _inPlaceEditBox.Text = args.Text; _startEditText = args.Text; AutosizeInPlaceEdit(); _inPlaceEditBox.Visible = true; _inPlaceEditBox.Focus(); } private void HandleInPlaceKeyDown( object sender, KeyEventArgs e ) { if ( e.KeyData == Keys.Escape ) { CloseEdit( false ); } else if ( e.KeyData == Keys.Enter ) { CloseEdit( true ); } } private void HandleInPlaceKeyPress( object sender, KeyPressEventArgs e ) { if ( !_inPlaceEditBox.Visible || e.KeyChar == '\r' || e.KeyChar == '\n' ) { e.Handled = true; } } private void HandleInPlaceLostFocus( object sender, EventArgs e ) { CloseEdit( true ); } private void HandleInPlaceTextChanged( object sender, EventArgs e ) { AutosizeInPlaceEdit(); } private void AutosizeInPlaceEdit() { using( Graphics g = _host.CreateGraphics() ) { Size desiredSize = _host.ControlPainter.MeasureText( g, _inPlaceEditBox.Text, _inPlaceEditBox.Font ); int desiredWidth = desiredSize.Width + 20; if ( desiredWidth > _inPlaceEditRect.Width ) { desiredWidth = _inPlaceEditRect.Width; } else if ( desiredWidth < 100 ) { desiredWidth = 100; } _inPlaceEditBox.Width = desiredWidth; } } protected void OnBeforeItemEdit( JetItemEditEventArgs args ) { if ( BeforeItemEdit != null ) { BeforeItemEdit( this, args ); } } protected void OnAfterItemEdit( JetItemEditEventArgs args ) { if ( AfterItemEdit != null ) { AfterItemEdit( this, args ); } } public void CloseEdit( bool save ) { if ( _inPlaceEditBox.Visible && !_closingInPlaceEdit ) { _closingInPlaceEdit = true; if ( _inPlaceEditBox.Text != _startEditText ) { JetItemEditEventArgs args = new JetItemEditEventArgs( save ? _inPlaceEditBox.Text : null, _editNode.Data, _editColumn ); OnAfterItemEdit( args ); } _host.SetEditedNode( null ); _inPlaceEditBox.Visible = false; _host.Focus(); _closingInPlaceEdit = false; } } } public class JetItemEditEventArgs { private string _text; private object _item; private JetListViewColumn _column; private bool _cancelEdit; public JetItemEditEventArgs( string text, object item, JetListViewColumn column ) { _text = text; _item = item; _column = column; _cancelEdit = false; } public string Text { get { return _text; } set { _text = value; } } public object Item { get { return _item; } } public JetListViewColumn Column { get { return _column; } } public bool CancelEdit { get { return _cancelEdit; } set { _cancelEdit = value; } } } public delegate void JetItemEditEventHandler( object sender, JetItemEditEventArgs e ); }