能够切换插入/改写状态的 TextBox

类别:.NET开发 点击:0 评论:0 推荐:

.Net FCL 中的 System.Windows.Forms.TextBox 是一个常用的控件,然而此控件不支持插入/改写状态的切换功能。本文介绍如何来为 System.Windows.Forms.TextBox 添加此功能。

以下是本控件的全部源代码,您可以加入一个项目中直接编译以生成该控件。

 注意:本控件禁止了 Multiline 功能,还有一个小 BUG 没有处理掉。

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace Effortech.Library.Controls
{
 /// <summary>
 /// 能够切换插入/改写状态的文本框控件
 /// </summary>
 public class OverWritableTextBox : System.Windows.Forms.TextBox
 {

  #region Class Variables
  private bool isOverWrite = false;
  #endregion

  #region Constructors
  public OverWritableTextBox()
  {
   base.Multiline = false;
  }

  #endregion

  #region Overrides
  protected override void OnGotFocus(EventArgs e)
  {
   base.OnGotFocus(e);

   this.ForceSelectOneChar();
  }
   
  protected override void OnMouseUp(MouseEventArgs e)
  {
   base.OnMouseUp (e);
   if (e.Button == MouseButtons.Left)
   {
    this.ForceSelectOneChar();
   }  
  }

  protected override void OnTextChanged(EventArgs e)
  {
   base.OnTextChanged (e);

   this.ForceSelectOneChar();
  }

  protected override void OnKeyPress(KeyPressEventArgs e)
  {
   base.OnKeyPress (e);
   if ((e.KeyChar == (char)8) &&
    this.isOverWrite )
   {
    this.SelectionLength = 0;
   }
  }

  protected override void OnReadOnlyChanged(EventArgs e)
  {
   base.OnReadOnlyChanged (e);
   if (this.ReadOnly)
   {
    this.isOverWrite = false;
    this.SelectionLength = 0;
   }
  }

  protected override void OnEnabledChanged(EventArgs e)
  {
   base.OnEnabledChanged (e);
   if (this.Enabled == false)
   {
    this.isOverWrite = false;
    this.SelectionLength = 0;
   }
  }


  protected override void OnKeyUp(KeyEventArgs e)
  {
   base.OnKeyUp(e);

   // 此处重写 OnKeyUp 并调用 ForceSelectOneChar 方法的唯一原因:
   //      当组合使用 Shift/Ctrl 和移动键时,可能会使得
   //      this.SelectionLength 为 0,这在改写状态下是不希望出现的。
   //
   // BUG ——
   // 执行以下方法的负面效果是:如果使用 Shift + 左移键,当取消了所选中的字符时,
   // 控件会强制选取一个字符,这就使得左移键看起来失效了。
   // 但是此时用户操作只要不放开左移键,仍可继续往左移动光标。
   //
   // 应采用 Win32 KeyBoard API 来监测 Shift/Ctrl 键的弹出事件,然后再调用以下方法才比较妥当。
   // 以后再补吧。
   // 如果哪位兄台有什么高见,一定要告诉我哦。
   this.ForceSelectOneChar();
  }


  protected override void OnKeyDown(KeyEventArgs e)
  {
   base.OnKeyDown(e);
   switch(e.KeyCode)
   {
    case Keys.Insert:
     if (this.ReadOnly == false)
     {
      if ( this.isOverWrite )
      {
       this.isOverWrite = false;
      }
      else
      {
       this.isOverWrite = true;
       this.ForceSelectOneChar();
      }
     }
     break;

    case Keys.Left:
    case Keys.Up:
     if ( this.isOverWrite &&  // 不对有 Shift 或 Ctrl 键按下时进行任何处理。
      (Control.ModifierKeys & Keys.Shift) != Keys.Shift &&
      (Control.ModifierKeys & Keys.Control) != Keys.Control )
     {
      if ( this.SelectionStart > 0)
      {
       this.SelectionStart--;
       this.SelectionLength = 1;
      }
      e.Handled = true;
     }
     break;

    case Keys.Right:
    case Keys.Down:
     if ( this.isOverWrite &&  // 不对有 Shift 或 Ctrl 键按下时进行任何处理。
      (Control.ModifierKeys & Keys.Shift) != Keys.Shift &&
      (Control.ModifierKeys & Keys.Control) != Keys.Control)
     {
      if ( this.SelectionStart < this.Text.Length)
      {
       this.SelectionStart = this.SelectionLength + this.SelectionStart;
       this.SelectionLength = 1;
      }
      e.Handled = true;
     }
     break;
    default:
     this.ForceSelectOneChar();
     break;
   }
  }

  #endregion

  /// <summary>
  /// 改写状态下,若没有选取任何字符,强制必须至少选取一个字符。
  /// </summary>
  private void ForceSelectOneChar()
  {
   if (this.isOverWrite && this.SelectionLength == 0)
   {
    this.SelectionLength = 1;   // 此操作当已位于最后一个位置时无效,但并不会抛出异常。
   }
  }
   
  /// <summary>
  /// 因为本控件没有处理多行方式下的改写功能,所以暂禁。
  /// </summary>
  [Browsable(false)]
  public new bool Multiline
  {
   get
   {
    return base.Multiline;
   }
   set
   {
    if (value == true)
     throw new NotSupportedException();

    base.Multiline = value;
   }
  }

  /// <summary>
  /// 获取是否处于改写状态
  /// 暂时认为没有必要提供本属性的设置(set)操作
  /// </summary>
  public bool OverWriting
  {
   get
   {
    return this.isOverWrite;
   }
  }
  
 }
}

最后向 CMIC(大象)致谢。

本文地址:http://com.8s8s.com/it/it43895.htm