Wie bestehen ich ein ByRef Variable in .net winforms Dialogform?
-
02-07-2019 - |
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
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();