vbAccelerator - Contents of code file: CancellableEditPopupCS_EditableListBox.csusing System;
using System.Drawing;
using System.Windows.Forms;
namespace vbAccelerator.Components.Controls
{
/// <summary>
/// A derived ListBox control allows items to be edited in place
/// </summary>
public class EditableListBox : ListBox
{
private bool readOnly = false;
private int lastSelectedIndex = -1;
private PopupCancelNotifier popupNotifier = null;
private TextBox txtPopupEdit = null;
/// <summary>
/// Gets/sets whether the ListBox can be edited or not.
/// </summary>
public bool ReadOnly
{
get
{
return this.readOnly;
}
set
{
this.readOnly = value;
}
}
/// <summary>
/// Starts editing the specified item.
/// </summary>
/// <param name="index">0-based index of item to edit</param>
public void StartItemEdit(int index)
{
// Stop editing if we are:
EndTextEdit(false);
// Select the item:
this.lastSelectedIndex = index;
this.SelectedIndex = index;
// is the item visible?
// start editing:
StartTextEdit();
}
/// <summary>
/// Ends editing if we are editing, setting whether to commit
/// changes or not.
/// </summary>
public void EndItemEdit(bool commit)
{
if (txtPopupEdit.Visible)
{
EndTextEdit(commit);
}
}
/// <summary>
/// Raises the <see cref="SelectedIndexChanged"/>
/// event and performs processing to ensure items can be edited
/// </summary>
/// <param name="e">Not used</param>
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
lastSelectedIndex = base.SelectedIndex;
}
/// <summary>
/// Raises the <see cref="MouseDown"/>
/// event and starts editing in place if appropriate.
/// </summary>
/// <param name="e">Mouse information associated with the event.</param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if ((!ReadOnly) && (e.Button == MouseButtons.Left))
{
if (!txtPopupEdit.Visible)
{
if ((base.SelectedIndex == lastSelectedIndex) &&
(lastSelectedIndex > -1))
{
StartTextEdit();
}
}
}
}
/// <summary>
/// Responds to the <see cref="PopupCancelNotifier"/> <see
cref="PopupCancel"/>
/// event.
/// </summary>
/// <param name="sender">PopupCancelNotifier object which sent the
event</param>
/// <param name="e"><see cref="PopupCanceEventArgs"/> describing the
cancel event.</param>
private void popupNotifier_PopupCancel(object sender,
PopupCancelEventArgs e)
{
EndTextEdit(true);
}
/// <summary>
/// Responds to the <see cref="KeyDown"/> event on the popup edit text
/// control to allow end and cancel edit on Return and Escape keys
/// </summary>
/// <param name="sender">TextBox which sent the event</param>
/// <param name="e"><see cref="KeyEventArgs"/> describing the key
event.</param>
private void txtPopupEdit_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyData)
{
case Keys.Return:
// end editing:
EndTextEdit(true);
e.Handled = true;
break;
case Keys.Escape:
// cancel editing:
EndTextEdit(false);
e.Handled = true;
break;
}
}
/// <summary>
/// Internal method to start editing.
/// </summary>
private void StartTextEdit()
{
this.Focus();
txtPopupEdit.Text = (String) base.SelectedItem;
if (txtPopupEdit.Text.Length > 0)
{
txtPopupEdit.SelectionStart = 0;
txtPopupEdit.SelectionLength = txtPopupEdit.Text.Length;
}
txtPopupEdit.Tag = base.SelectedItem;
Rectangle bounds = GetListBoxItemBounds();
txtPopupEdit.Location = bounds.Location;
txtPopupEdit.Size = bounds.Size;
txtPopupEdit.Visible = true;
txtPopupEdit.BringToFront();
txtPopupEdit.Focus();
popupNotifier.StartTracking(txtPopupEdit);
}
/// <summary>
/// Gets the bounding rectangle of the selected item in the ListBox
/// </summary>
/// <returns><see cref="System.Drawing.Rectangle"/> containing the
/// bounds of the item on screen.</returns>
protected virtual Rectangle GetListBoxItemBounds()
{
int itemHeight = base.ItemHeight;
int selectedIndex = base.SelectedIndex;
int top = (selectedIndex - base.TopIndex) * itemHeight;
return new Rectangle(0, top, base.ClientRectangle.Width, itemHeight);
}
/// <summary>
/// Internal method to end text editing and optionally commit changes.
/// </summary>
/// <param name="commit">Whether changes should be committed or
not.</param>
private void EndTextEdit(bool commit)
{
if (commit)
{
base.Items[base.SelectedIndex] = txtPopupEdit.Text;
}
else
{
// do nothing
}
txtPopupEdit.Visible = false;
popupNotifier.StopTracking();
}
/// <summary>
/// Constructs a new instance of the editable ListBox
/// </summary>
public EditableListBox() : base()
{
popupNotifier = new PopupCancelNotifier();
popupNotifier.PopupCancel += new
PopupCancelEventHandler(popupNotifier_PopupCancel);
txtPopupEdit = new System.Windows.Forms.TextBox();
txtPopupEdit.KeyDown += new KeyEventHandler(txtPopupEdit_KeyDown);
//
// txtPopupEdit
//
this.txtPopupEdit.AcceptsReturn = true;
this.txtPopupEdit.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txtPopupEdit.Location = new System.Drawing.Point(128, 216);
this.txtPopupEdit.Name = "txtPopupEdit";
this.txtPopupEdit.Multiline = true;
this.txtPopupEdit.Size = new System.Drawing.Size(144, 14);
this.txtPopupEdit.TabIndex = 0;
this.txtPopupEdit.Text = "";
this.txtPopupEdit.Visible = false;
this.Controls.AddRange( new Control[] { txtPopupEdit });
}
}
}
|
|