Comment empêcher les événements de valeur changée de s'allumer lors de l'initialisation du formulaire in.NET Je ne sais pas.
envisagez un simple formulaire .NET avec quelques boutons radio et une case à cocher.
chacun des boutons radio a une configuration de handler CheckedChanged qui effectue une action basée sur l'état de la case à cocher.
mon problème est que, lorsque j'initialise sur le bouton radiobutton par défaut à vérifier (à partir de la fenêtre des propriétés du concepteur) , L'événement CheckedChanged est déclenché pour ce bouton radio, mais la case à cocher n'a pas encore été initialisée, donc j'obtiens soit une exception de pointeur nul. ou la mauvaise valeur est utilisée dans le gestionnaire. Quoi qu'il en soit, je ne veux pas que ce code de gestionnaire soit exécuté à moins que l'utilisateur ne sélectionne un bouton radio après que le formulaire ait été chargé.
Je m'en sors actuellement en n'initialisant pas le bouton radio, mais j'ai besoin de régler ce défaut éventuellement et le meilleur endroit est celui du concepteur. Je peux aussi ajouter un champ booléen qui n'est pas défini à true, jusqu'à ce que le formulaire est entièrement chargé et ne pas traiter les événements si c'est faux, mais c'est un sale hack.
Que puis-je faire pour empêcher ce gestionnaire d'exécuter son code?
10 réponses
" je peux aussi mettre un champ booléen qui n'est pas défini à true jusqu'à ce que la forme soit entièrement chargée et ne pas traiter les événements si c'est faux, mais c'est un piratage sale."
C'est aussi les plus faciles, et le meilleur moyen de le faire!
disons que .NET fournit une façon soignée de désactiver tous les gestionnaires d'événements jusqu'à ce que le formulaire soit chargé. Même ceux que vous manipulez. Il ne serait toujours pas suffisamment flexible pour désactiver ce que vous vouliez activer mais désactiver ce que vous n'avez pas. Souvent les configurations de forme arrivent et vous voulez que les événements se déclenchent. De plus, le formulaire ne sera pas construit correctement si aucun événements feu.
Pour faire sentir un peu moins sale, si vous initialisez les contrôles dans le constructeur du formulaire que vous pourriez être en mesure d'utiliser les formulaires IsHandleCreated propriété plutôt que votre propre bool pour vérifier si elle devrait effectivement valider ou non.
Je pense que normalement vous ne voudriez pas valider quoi que ce soit avant qu'il ait été montré pour la première fois et handle n'est pas créé jusqu'à ce qu'il le soit.
Exemple De Code:
Private Sub myRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles myRadioButton.CheckedChanged
If myRadioButton.Checked AndAlso myRadioButton.IsHandleCreated Then
'Do Work
End If
End Sub
LA solution facile est de déclarer une variable d'initialisation:
Private Initializing as boolean = True
Private Sub rb_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbNuevos.CheckedChanged, RbDesaparecidos.CheckedChanged, RbModificados.CheckedChanged, RbNoDesap.CheckedChanged, RbDesHoy.CheckedChanged, RbChT.CheckedChanged
if Initializing then return
'Your Code
End Sub
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
initializing = false
end sub
plus sophistiqué: enlever les "poignées" de la méthode, et utiliser AddHandler
sur la nouvelle méthode.
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
AddHandler RbChT.CheckedChanged, AddressOf rb_CheckedChanged
end sub
radiobutton
voir Hans Olsson answer
numérique (de haut en bas, de faire comme ceci
Private Sub myNumeric_ValueChanged(sender As Object, e As EventArgs) Handles myNumeric.ValueChanged
If myNumeric.Value >= 0 AndAlso myNumeric.IsHandleCreated Then
'Do the work
End If
End Sub
Le mot-clé est myNumeric.Value
et IsHandleCreated
Encore une autre façon:
Private Sub dgvGroups_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvGroups.CellValueChanged
If Me.Visible = False Then Exit Sub ' Sub gets called on form load which causes problems
wksGroups.Cells(e.RowIndex + 1, 1) = dgvGroups.Item(e.ColumnIndex, e.RowIndex).Value
wksGroups.Cells(1, 5) = dgvGroups.RowCount
Une chose que j'ai trouvé qui fonctionne est d'ajouter les événements manuellement après avoir charger le formulaire.
pour ce faire, vous pouvez simplement aller dans le code de formulaire généré trouvé dans le fichier designer de ce formulaire, et extraire les lignes qui ajoutent l'événement. Il ressemblerait à quelque chose comme ceci:
this.controlName.CheckedChanged += new System.EventHandler(this.controlName_CheckedChanged);
puis mettez tous ces appels dans une méthode que vous appelez après L'appel InitializeComponent dans le constructeur de votre forme.
juste au cas où quelqu'un est encore à la recherche de cela l'événement est lancé lors de l'initialisation du formulaire mais le formulaire n'est pas encore visible, dites aussi que vous avez une relation clé étrangère sur laquelle vous avez une valeur par défaut nécessaire problème qui est lancé chaque mise à jour de ligne aussi. Donc le code suivant a fonctionné pour moi....
if (Visible && !(e.ColumnIndex == 0))
{
phoneEdited = true;
MessageBox.Show("A Phone entry has been entered");
}
- Ne définissez pas vérifié sur un contrôle qui n'a vraiment beaucoup dans designer.
- le drapeau mondial et les sorties conditionnelles là où c'est nécessaire.
- Essayer..Attraper les points sensibles pour ignorer une exception insignifiante.
(en utilisant VS 2017) il me semble que c'est un ennui mais pas un bug. Il est compatible avec le modèle en cours d'utilisation. L'événement est déclenché par le fonctionnement normal du code, mais le code que je n'ai pas écrit (mais peut accéder où les idiots ont peur de marcher) et où il ne semble pas (décent) lieu plus tôt dans le flux normal de l'anticiper.
la réponse la plus claire semble être de ne pas vérifier les boutons radio ou les cases à cocher dans le concepteur du tout s'ils déclenchent un code significatif. Au lieu de cela, ces contrôles doivent être modifiés par le code (par exemple checked = true) dans L'événement de chargement (par exemple) après que toute l'initialisation est faite.
il n'y a pas de perte de flexibilité ici puisque les deux sont fixés avant la construction, seulement à des endroits différents. Les gestionnaires d'événements le manipuleront exactement comme si un utilisateur avait cliqué sur le contrôle dans le flux naturel d'une application GUI bien conçue. (Cela me rappelle l'ancien proverbe RPG "don't buck the cycle". (Quelqu'un ici se souvient de RPG? Je ne fais pas partie de L'équipe IBM, Je ne l'ai jamais utilisé, mais j'ai eu des discussions intéressantes avec certains qui l'ont fait. ) Les contrôles de pré-vérification frappent la mauvaise partie du cycle VS.)
si pour une raison quelconque cela ne fonctionne pas, la meilleure chose suivante est le kludge suggéré ailleurs d'un seul Statut booléen initialisé false et mis true au moment approprié avec sorties conditionnelles dans les endroits nécessaires pour les empêcher de s'écraser jusqu'à ce moment-là. Il va faire le travail, mais c'est moche. Mieux que l'échec.
une autre chose que j'ai essayé avant de décider que les vérifications prédéfinies au niveau du concepteur étaient le problème et qu'il y avait une alternative très acceptable était de mettre les points dangereux dans un essai..Attraper pour pouvoir ignorer l'exception. Aussi un bidouille.
peut-être que pour certaines fonctionnalités, vous pouvez utiliser l'événement click au lieu de l'événement check changed.
j'ai mis une variable publique dans le fichier Module1 Dim public bolForm_LoadingTF as Boolean = True
dans chaque formLoad que j'ai mis bolForm_LoadingTF = True
dans chaque contrôle avec un Onselectedeinchanged event I put if bolForm_LoadingTF = True then Exit Sub
À la fin de l'événement load du formulaire j'ai mis bolForm_LoadingTF = False
je suis probablement la rupture d'un tas de règles, mais cela fonctionne m'.