web-dev-qa-db-fra.com

Modification du texte de la zone de texte sans déclencher un événement TextChanged

Mon application dans C# a une Textbox avec un événement txt_TextChanged

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

Mais il y a une partie spécifique que je veux modifier txt.Text sans déclencher l'événement txt_TextChanged.

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

Comment puis je faire ça?

10
Alex Jolig

Il n'existe aucun moyen direct d'empêcher la génération d'événements pour la propriété text. Toutefois, votre gestionnaire d'événements peut utiliser un indicateur pour déterminer la météo ou non pour effectuer une tâche. C'est probablement plus efficace que d'attacher et de détacher le gestionnaire d'événements. Cela peut être fait par une variable dans la page ou même un wrapper de classe spécialisé

Avec une variable:

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

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

Avec wrapper de gestionnaire d'événements spécialisé

   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);
    }
}
12
Austin
txt.TextChanged -= textBox1_TextChanged;  // dettach the event handler
txt.Text = "something"; // update value
txt.TextChanged += textBox1_TextChanged; // reattach the event handler
8
Balanikas

Vous pouvez étendre la zone de texte et y introduire une nouvelle propriété qui ne déclenchera pas l'événement 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);
            }
        }
    }
5
Kuba

essayez cette méthode d'extension

  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);
    }
}

vous pouvez utiliser textbox.SetText ("...") pour modifier le texte et l'événement TextChanged ne sera pas déclenché.

5
Mitz

Une façon rapide et sale est de faire un 

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

puis dans l'événement OnChange, encapsulez le code incriminé avec un

if (ctrl.Enabled) {
  // offending code here.
}
1
Dan Mecklenburg
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");
    }
}
0
AsfK