Question

Je crée un "sélecteur de département". formulaire qui va servir de formulaire contextuel modal avec bon nombre de mes "primaires" formes d'une application Winforms. Idéalement, l'utilisateur va cliquer sur une icône en regard d'une zone de texte qui fera apparaître le formulaire, il sélectionnera le service dont il a besoin et, lorsqu'il cliquera sur OK, la boîte de dialogue se fermera et la valeur sélectionnée pour moi mettre à jour la zone de texte avec.

J'ai déjà fait la route en passant le propriétaire de la boîte de dialogue dans le formulaire de dialogue et en faisant en sorte que l'événement de clic du bouton OK effectue la mise à jour appropriée, mais cela m'oblige à faire un DirectCast pour le type de formulaire et je peux alors réutilisez uniquement le sélecteur sur le formulaire actuel.

J'ai pu utiliser une variable ByRef dans le constructeur et mettre à jour une valeur, mais cela ne fonctionne que dans le constructeur. Si j'essaie d'attribuer la valeur ByRef à une variable interne de la classe Sélecteur de département, je perds son aspect de référence. Ceci est mon code de base attaché à mon formulaire:

Public Class DeptPicker

   Private m_TargetResult As String

   Public Sub New(ByRef TargetResult As String)

      InitializeComponent()

      ' This works just fine, my "parent" form has the reference value properly updated.
      TargetResult = "Booyah!"

      ' Once I leave the constructor, m_TargetResult is a simple string value that won't update the parent
      m_TargetResult = TargetResult

   End Sub

   Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click

      DialogResult = Windows.Forms.DialogResult.OK

      ' I get no love here. m_TargetResult is just a string and doesn't push the value back to the referenced variable I want.
      m_TargetResult = "That department I selected."
      Me.Close()

   End Sub

   Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

      DialogResult = Windows.Forms.DialogResult.Cancel
      Me.Close()

   End Sub

End Class

Quelqu'un peut-il me dire ce qui me manque ou une approche différente pour y arriver?

Remarque: l'exemple de code est dans VB.NET, mais je vais aussi prendre toutes les réponses C #. 8 ^ D

Était-ce utile?

La solution

Dans de tels cas, je généralement

  • Ecrivez une fonction ShowDialog qui fait ce que je veux (par exemple, renvoyer la valeur) ou
  • Laissez le résultat être une propriété dans la boîte de dialogue. Voici comment les dialogues de fichiers courants le font dans la BCL. L'appelant doit ensuite lire la propriété pour obtenir le résultat. C'est bien à mon avis.

Vous pouvez également combiner ces méthodes en faisant de la valeur du résultat une propriété dans la boîte de dialogue et en créant une méthode ShowDialog qui renvoie cette valeur de propriété, sous la forme ByRef à votre guise ou en tant que valeur de retour, en fonction de vos besoins.

Je vais ajouter ceci en tant qu'instruction d'utilisation, par exemple (désolé, aucun VB ici et vous avez dit que C # était le bienvenu):

using (var dlg = new DeptPicker()) {
    if (dlg.ShowDialog() == DialogResult.OK) {
        myTextBoxOrWhatEver.Text = dlg.TargetResult;
    }
}

Dans la boîte de dialogue elle-même, procédez comme suit:

void okButton_Click(object sender, EventArgs e)
{
    TargetResult = whatever; // can also do this when the selection changes
    DialogResult = DialogResult.OK;
    Close();
}

Je n'ai cependant pas utilisé la nouvelle implémentation de ShowDialog dans cet exemple.

Autres conseils

Le problème est que l’attribution de TargetResult au constructeur utilise la chaîne comme référence. La chaîne m_TargetResult est simplement une copie de la chaîne de référence, pas une référence à la chaîne d'origine.

Pour savoir comment créer un " pointeur " à l'original, je ne sais pas.

Cela est rendu encore plus difficile par le fait que VB.NET ne prend pas en charge les blocs de code non sécurisés, vous ne pouvez donc pas faire de référence de pointeur à la chaîne.

Vous pouvez transmettre la référence de la zone de texte au formulaire modal.

Laisser l'utilisateur choisir n'importe quel département. Lorsque l'utilisateur clique sur OK, définissez la propriété text de la zone de texte référencée sur le texte ou l'ID du service choisi (selon vos besoins)

J'utilise le code fourni par vous.


Public Class DeptPicker

   Private m_TargetTextBox As TextBox

   Public Sub New(ByRef TargetTextBox As TextBox)
      InitializeComponent()

      m_TargetTextBox = TargetTextBox

   End Sub

   Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click

      DialogResult = Windows.Forms.DialogResult.OK

      ' I get no love here. m_TargetResult is just a string and doesn't push the value back to the referenced variable I want.
      m_TargetTextBox.Text = "That department I selected."
      Me.Close()

   End Sub

   Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

      DialogResult = Windows.Forms.DialogResult.Cancel
      Me.Close()

   End Sub

End Class


Public Class DeptPicker

    dim dlgResult as DialogResult

    Public Function GetSelectedDepartment() As String
        Me.Show vbModal
        If (dlgResult = Windows.Forms.DialogResult.OK) Then
            return "selected department string here"
        Else
            return "sorry, you didnt canceled on the form"
        End If
    End Function

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        dlgResult = Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        dlgResult = Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub
End Class

Remarque: je n'ai pas testé cela. J'espère que vous avez une idée de ce que je veux dire.

OregonGhost: Est-ce que cela a l'air mieux?

L'utilisateur peut appeler new DeptPicker (). GetSelectedDepartment (). Je ne savais pas que je n'avais plus besoin de poster la réponse & amp; pourrait utiliser le même message.

Merci, OregonGhost. Maintenant, ça vous va?

Cela peut fonctionner:

    // This code in your dialog form.  Hide the base showdialog method 
    // and implement your own versions
    public new string ShowDialog() {
        return this.ShowDialog(null);
    }

    public new string ShowDialog(IWin32Window owner) {
        // Call the base implementation of show dialog
        base.ShowDialog(owner);

        // You get here after the close button is clicked and the form is hidden.  Capture the data you want.
        string s = this.someControl.Text;

        // Now really close the form and return the value
        this.Close();
        return s;
    }

    // On close, just hide.  Close in the show dialog method
    private void closeButton_Click(object sender, EventArgs e) {
        this.Hide();
    }

    // This code in your calling form
    MyCustomForm f = new MyCustomForm();
    string myAnswer = f.ShowDialog();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top