2008-10-25 10 views
2

J'ai un bouton radio sur mon formulaire Windows. Comment puis-je déterminer si l'événement CheckChanged a eu lieu en raison d'un utilisateur en cliquant ou en sélectionnant le bouton radio vs réglage programatically l'événement avecComment déterminer si radioButton.Checked est défini par programmation ou par un clic de souris?

this.radioButtonAdd.Checked = true; 

Je voudrais un peu de code pour prendre une autre action en fonction de si l'utilisateur a cliqué sur le bouton ou j'ai soulevé l'événement moi-même.

Ou peut-être la meilleure question est comment puis-je gérer l'événement lorsqu'un utilisateur clique vs lorsque l'état est changé dans mon code.

Répondre

2

Je pense avoir trouvé une assez bonne réponse. Toutes les commandes Windows Forms ont une propriété appelée "Tag". sa valeur peut être n'importe quel objet.

Donc, si je veux Ingore tout changement programmatiques que je peux faire ce qui suit:

radioButton.Tag = "ignore" 
radioButton.Checked = true 

puis dans le gestionnaire d'événements:

private void radioButton_CheckedChanged(object sender, EventArgs e) 
{ 
    if (radioButton.Checked) 
    { 
     // Tag will be null in cases where the user clicks 
     if (this.radioButtonAdd.Tag == null) 
     { 
      // do something 
     } 
     else 
     { 
      // swallow action 
      // reset Tag 
      this.radioButtonAdd.Tag = null; 
     } 
    } 
} 
2

S'il existe une méthode intégrée, je ne suis pas au courant. Une manière de le gérer consiste à définir un indicateur global pendant que le code effectue des modifications qui indiquent le gestionnaire d'événements. Par exemple, le code qui rend les changements pourrait ressembler à quelque chose comme ce qui suit:

savedFlag = modifyingProgrammatically; 
modifyingProgrammatically = true; 
this.radioButtonAdd.Checked = true; 
modifingProgrammatically = savedFlag; 

Au sein de votre gestionnaire d'événements:

if(modifyingProgramatically) { 
    // The event was raised by an assignment within the code. 
} else { 
    // The event was raised by a user action. 
} 
1

Vous pouvez aussi faire quelque chose comme changer une valeur de champ de drapeau sur MouseDown pour le bouton radio, puis en inversant la valeur de l'indicateur sur MouseClick. Puisque l'événement CheckedChanged se déclenche entre les deux, il peut utiliser l'indicateur avant qu'il ne soit retourné par l'événement MouseClick, et vous n'avez pas à vous soucier de réinitialiser son état.

Vous pouvez encore avoir des problèmes threading pour résoudre si vous utilisez un champ comme un drapeau (ne sais pas grand-chose à propos de l'application que vous travaillez), mais quelque chose comme cela devrait fonctionner:

private bool _mouseEvent; 
    private void radioButton1_CheckedChanged(object sender, EventArgs e) 
    { 
     if (_mouseEvent) 
      MessageBox.Show("Changed by mouse click."); 
     else 
      MessageBox.Show("Changed from code."); 
    } 

    private void radioButton1_MouseClick(object sender, MouseEventArgs e) 
    { 
     _mouseEvent = false; 
    } 

    private void radioButton1_MouseDown(object sender, MouseEventArgs e) 
    { 
     _mouseEvent = true; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // This simulates a change from code vs. a change from 
     // a mouse click. 
     if (radioButton1.Checked) 
      radioButton2.Checked = true; 
     else 
      radioButton1.Checked = true; 
    } 

Alternativement, vous pouvez séparer votre logique d'application "clic-souris seulement" afin qu'elle soit déclenchée par un événement différent (comme MouseClick).

Espérons que cela aide.

Questions connexes