Изменение текста Textbox без запуска события TextChanged

Мои приложения C# есть Textbox С txt_TextChanged событие.

private void txt_TextChanged(object sender, EventArgs e)
{
  //Do somthin
}

но есть одна конкретная часть, которую я хочу изменить txt.Text без стрельбы txt_TextChanged событие.

txt.Text ="somthing" //Don't fire txt_TextChanged

как я могу это сделать?

6 ответов


нет прямого способа предотвратить возникновение событий для свойства text, однако обработчик событий может использовать флаг для определения погоды или не выполнять задачу. Это я, вероятно, будет более эффективным, чем присоединение и отсоединение обработчика событий. Это может быть сделано переменной на странице или даже специализированной оболочкой класса

переменной:

skipTextChange = true;
txt.Text = "Something";

protected void TextChangedHandler(object sender, EventArgs e) {
  if(skipTextChange){ return; }
  /// do some stuffl
}

С помощью специализированной оболочки обработчика событий

   var eventProxy = new ConditionalEventHandler<EventArgs>(TextBox1_TextChanged);
    TextBox1.TextChanged = eventProxy.EventAction;

    eventProxy.RaiseEvents = false;
    TextBox1.Text = "test";


    public void TextBox1_TextChanged(object sender, EventArgs e) {
       // some cool stuff;
    }

    internal class ConditionalEventHadler<TEventArgs> where TEventArgs : EventArgs
{
   private Action<object,TEventArgs> handler;

    public bool RaiseEvents {get; set;}

    public ConditionalEventHadler(Action<object, TEventArgs> handler)
    {
        this.handler = handler; 
    }

    public void EventHanlder(object sender, TEventArgs e) {
      if(!RaiseEvents) { return;}
      this.handler(sender, e);
    }
}

вы можете расширить текстовое поле и ввести там новое свойство, которое не вызовет событие TextChanged.

    class SilentTextBox : TextBox
    {
        // if true, than the TextChanged event should not be thrown
        private bool Silent { get; set; }

        public string SilentText
        {
            set
            {
                Silent = true;
                Text = value;
                Silent = false;
            }
        }

        protected override void OnTextChanged(EventArgs e)
        {
            // raise event only if the control is in non-silent state
            if (!Silent)
            {
                base.OnTextChanged(e);
            }
        }
    }

txt.TextChanged -= textBox1_TextChanged;  // dettach the event handler
txt.Text = "something"; // update value
txt.TextChanged += textBox1_TextChanged; // reattach the event handler

попробуйте этот метод расширения

  public static class TextBoxExt
{
    private static readonly FieldInfo _field;
    private static readonly PropertyInfo _prop;

    static TextBoxExt()
    {
        Type type = typeof(Control);
        _field = type.GetField("text", BindingFlags.Instance | BindingFlags.NonPublic);
        _prop = type.GetProperty("WindowText", BindingFlags.Instance | BindingFlags.NonPublic);
    }

    public static void SetText(this TextBox box, string text)
    {
        _field.SetValue(box, text);
        _prop.SetValue(box, text, null);
    }
}

вы можете использовать textbox.Помощью setText("...") изменить текст и событие TextChanged не будут запущены.


быстрый и грязный способ сделать

ctrl.Enable = false; 
ctrl.Text = "Something";
ctrl.Enable = true;

а затем в событии OnChange инкапсулируйте оскорбительный код с помощью

if (ctrl.Enabled) {
  // offending code here.
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        EventHandler TextChanged_EventHandler = new EventHandler(textBox1_TextChanged);
        textBox1.TextChanged -= TextChanged_EventHandler;
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        MessageBox.Show("BUG");
    }
}