2017-05-08 1 views
2

Je migre un code hérité de VB6 vers VB.NET et j'ai rencontré un problème ennuyeux. Ce qui se passe actuellement est l'utilisateur est fourni avec RadionButton contrôles pour indiquer la hiérarchie. Quand ils choisissent une valeur, le code vérifie qu'il est valide (C ne peut pas être l'enfant de A, doit être l'enfant de B) et si ce n'est pas le cas, il renvoie le RadioButton au paramètre d'origine. Le problème est que lorsque la fonction qui en résulte retourne au gestionnaire d'événements, elle renvoie l'état RadioButton à la façon dont elle a été cliquée (l'utilisateur a cliqué sur C, le code l'a renvoyé à B, quand la fonction quitte, il retourne à C déclencher l'événement qui le rendra à nouveau B, etc., etc. provoquant une boucle infinie). Y a-t-il un moyen de changer quel événement RadioButton is selected inside a function called by CheckedChanged` et le faire coller?Modifier le contrôle de validation RadioButton dans l'événement

Je sais que la meilleure conception est de désactiver les contrôles RadioButton invalides à l'avance, mais c'est ainsi que cela a été conçu et mon travail consiste à le faire fonctionner dans un temps limité, donc je suis coincé avec un mauvais design maintenant opposé à une bonne conception plus tard.

code:

Private Sub optIndent_2_ClickEvent(sender As Object, e As EventArgs) Handles optIndent_2.CheckedChanged 
    optIndent_Click(2, sender.Checked) 
End Sub 

Private Sub optIndent_3_ClickEvent(sender As Object, e As EventArgs) Handles optIndent_3.CheckedChanged 
    optIndent_Click(3, sender.Checked) 
    Dim i As Integer = 1 
End Sub 

Private Sub optIndent_Click(ByRef Index As Short, ByRef value As Short) 
    If value = False Then 
     Exit Sub 
    End If 

    If Index = 2 Then 
     Exit Sub 
    End If 
    If Index = 3 Then 
     optIndent_2.Checked = True 
     Exit Sub 
    End If 
End Sub 

Vous verrez que lorsque le code sort optIndent_Click (3, sender.checked) la valeur passera de false à true, le processus se répétera jamais.

Répondre

2

Le problème est l'utilisation de ByRef:

Specifies that an argument is passed in such a way that the called procedure can change the value of a variable underlying the argument in the calling code.

Au lieu de cela vous devez utiliser ByVal:

Specifies that an argument is passed in such a way that the called procedure or property cannot change the value of a variable underlying the argument in the calling code.

Changer l'argument value être un argument ByVal va résoudre le problème. Cela empêchera value de conserver sa "valeur".

Je comprends que vous êtes coincé avec la mauvaise conception si cela peut ne pas entrer dans ce cadre, mais projette à un moment donné, vous devriez regarder tourner Option Strict On:

Restricts implicit data type conversions to only widening conversions, disallows late binding, and disallows implicit typing that results in an Object type.

Cela aurait mis en évidence ByVal value As Short comme un numéro:

Option Strict On disallows implicit conversions from 'Boolean' to 'Short'.

Le correctif serait; ByVal value As Boolean.

Avoir Option Strict On pourrait aussi mettre en évidence sender.Checked comme une erreur:

Option Strict On disallows late binding

Le correctif serait de jeter sender comme RadioButton de sorte que vous pouvez accéder directement à ses propriétés; DirectCast(sender, RadioButton).Checked.

Votre code ressemblerait à quelque chose comme:

Private Sub optIndent_2_ClickEvent(sender As Object, e As EventArgs) Handles optIndent_2.CheckedChanged 
    optIndent_Click(2, DirectCast(sender, RadioButton).Checked) 
End Sub 

Private Sub optIndent_3_ClickEvent(sender As Object, e As EventArgs) Handles optIndent_3.CheckedChanged 
    optIndent_Click(3, DirectCast(sender, RadioButton).Checked) 
End Sub 

Private Sub optIndent_Click(ByVal Index As Short, ByVal value As Boolean) 
    If value = False Then 
     Exit Sub 
    End If 

    If Index = 2 Then 
     Exit Sub 
    End If 

    If Index = 3 Then 
     optIndent_2.Checked = True 
     Exit Sub 
    End If 
End Sub