Frage

Ich schaffe eine „Abteilung Picker“ Form, die als modale Popup-Form mit vielen meiner „primären“ Formen einer WinForms-Anwendung dienen wird. Im Idealfall wird der Benutzer geht auf ein Symbol klicken, um neben einem Textfeld, das die Form auftauchen, werden sie die Abteilung die sie benötigen, zu wählen, und wenn sie auf OK klicken, wird das Dialogfeld schließen, und ich werde den Wert für mich ausgewählt haben aktualisieren Sie die Textbox mit.

Ich habe bereits die Strecke mit Passieren des Besitzers des Dialogfelds in das Dialogform und mit dem OK-Taste klicken Ereignis tut das richtige Update getan, aber dies zwingt mich eine Direct zum Formulartyp zu tun, und ich kann dann Wiederverwendung nur den Picker auf der aktuellen Form.

ich in der Lage gewesen, einen ByRef Variable im Konstruktor zu verwenden und erfolgreich einen Wert aktualisieren, aber es funktioniert nur im Konstruktor. Wenn ich den ByRef Wert auf einige interne Variable in der Abteilung Picker Klasse zuweisen versuchen, verliere ich den Referenz Aspekt davon. Das ist mein Grund Code zu meiner Form angehängt:

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

Kann mir jemand sagen, was ich hier fehlt oder einen anderen Ansatz, damit dies geschieht?

Hinweis: Codebeispiel ist in VB.NET, aber ich werde auch keine C # Antworten zu nehmen. 8 ^ D

War es hilfreich?

Lösung

In solchen Fällen habe ich in der Regel entweder

  • Schreiben Sie eine Funktion, die Showdialog tut, was ich will (zum Beispiel den Wert zurück) oder
  • Lassen Sie einfach das Ergebnis eine Eigenschaft im Dialog sein. Dies ist, wie die gemeinsamen Dateidialoge in der BCL tun. Der Anrufer muss dann die Eigenschaft liest das Ergebnis zu erhalten. Das ist in Ordnung meiner Meinung nach.

Sie können auch diese Methoden kombinieren, indem Sie eine Eigenschaft im Dialog des Ergebniswert zu machen und eine Showdialog-Methode erstellen, die diese Eigenschaft Wert zurückgibt, entweder als ByRef, wie Sie oder als Rückgabewert wollen, je nach Ihren Bedürfnissen.

Ich werde dies als Verbrauchanweisung hinzufügen, zum Beispiel (sorry, keine VB hier, und Sie sagen, C # willkommen ist):

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

Im Dialog selbst, gerade dies tun:

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

Ich habe allerdings nicht die neue Showdialog Implementierung in diesem Beispiel verwenden.

Andere Tipps

Das Problem ist, dass TargetResult im Konstruktor Zuordnung ist die Zeichenfolge als Referenz verwendet. Die m_TargetResult Zeichenfolge ist nur eine Kopie des ref string, kein Verweis auf die ursprüngliche Zeichenfolge.

Was, wie einen „Zeiger“ zu machen, um das Original, ich weiß es nicht.

Dies wird noch schwieriger durch die Tatsache, dass VB.NET nicht unsicher Codeblöcke nicht unterstützt, so dass Sie keinen Zeiger Verweis auf die Zeichenfolge machen.

Sie können das Textfeld Verweis auf das modale Formular übergeben.

Lassen Sie die Benutzer jede Abteilung wählen. Wenn der Benutzer auf OK klickt, die Eigenschaft Text des genannten Textes Abteilung Text oder ID gewählt (hängt davon ab, was Sie brauchen)

Ich bin mit dem Code, der von Ihnen zur Verfügung gestellt.


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

Hinweis: Ich habe nicht getestet. Ich hoffe, Sie Idee davon bekommen, was ich meine.

OregonGhost:? Ist dies besser aussehen

Der Benutzer kann neue nennen DeptPicker (). GetSelectedDepartment (). Ich weiß nicht, dass ich die Antwort nicht wieder brauche Post & könnte das gleiche Post verwendet werden.

Danke OregonGhost. Nun sieht es ok?

Das kann funktionieren:

    // 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();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top