using System; using System.ComponentModel; using System.Windows.Forms; using System.Drawing; namespace AppliStation.Util { public class ToolStripWeb2LikeTextBox : ToolStripTextBox { public ToolStripWeb2LikeTextBox() : base() { this.Text = string.Empty; } [Category("Action")] public event EventHandler TextChangedTriggerFired; private int textChangedTriggerInterval = 500; /// /// Interval time for TextChangedTriggerFired. /// [Category("Behavior")] [DefaultValue(500)] public virtual int TextChangedTriggerInterval { get { return textChangedTriggerInterval; } set { textChangedTriggerInterval = value; } } private string oldText = null; public void FireTextChangedTrigger(EventArgs e) { textChangeTriggerTimerStop(); if (oldText != this.Text) { if (TextChangedTriggerFired != null) { TextChangedTriggerFired(this, e); } oldText = this.Text; } } public void FireTextChangedTrigger() { FireTextChangedTrigger(EventArgs.Empty); } #region TextChange Timers /// /// Timer for TextChangedTriggerFired. /// protected Timer textChangeTriggerTimer = null; private void onTextUpdate(bool force) { textChangeTriggerTimerStop(); textChangeTriggerTimer = new Timer(); textChangeTriggerTimer.Tick += textChangeTriggerTimerTick; textChangeTriggerTimer.Interval = TextChangedTriggerInterval; textChangeTriggerTimer.Start(); } private void textChangeTriggerTimerTick(object sender, EventArgs e) { FireTextChangedTrigger(e); } private void textChangeTriggerTimerStop() { if (textChangeTriggerTimer != null) { textChangeTriggerTimer.Stop(); textChangeTriggerTimer = null; } } protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); if (Focused) { onTextUpdate(false); } } #endregion protected bool textIsEmpty = true; public override string Text { get { return textIsEmpty? string.Empty : base.Text; } set { bool changed = false; if (string.IsNullOrEmpty(value)) { if (! textIsEmpty) { changed = true; textIsEmpty = true; base.Text = EmptyText; } } else if (this.Text != value) { changed = true; textIsEmpty = false; base.Text = value; } if (changed) { FireTextChangedTrigger(EventArgs.Empty); base.OnTextChanged(EventArgs.Empty); updateForeColorInternal(); } } } private string emptyText = "(none)"; /// /// Gray text when textbox is empty and has not focus /// [Category("Appearance")] public virtual string EmptyText { get { return emptyText; } set { emptyText = value; if (textIsEmpty) { base.Text = emptyText; } } } private Color emptyForeColor = SystemColors.GrayText; /// /// Gray text color when textbox is empty and has not focus /// [Category("Appearance")] [DefaultValue(typeof(Color), "GrayText")] public virtual Color EmptyForeColor { get { return emptyForeColor; } set { emptyForeColor = value; updateForeColorInternal(); } } private Color foreColor = SystemColors.WindowText; public override Color ForeColor { get { return foreColor; } set { foreColor = value; updateForeColorInternal(); } } protected override void OnEnter(EventArgs e) { if (textIsEmpty) { base.Text = string.Empty; textIsEmpty = false; updateForeColorInternal(); } base.OnEnter(e); } protected override void OnLeave(EventArgs e) { if (string.IsNullOrEmpty(base.Text)) { base.Text = EmptyText; textIsEmpty = true; updateForeColorInternal(); } base.OnLeave(e); } private void updateForeColorInternal() { base.ForeColor = textIsEmpty? EmptyForeColor : ForeColor; } } }