3

我正在创建一个“部门选择器”表单,它将作为一个模式弹出表单,其中包含我的许多 Winforms 应用程序的“主要”表单。理想情况下,用户将单击将弹出表单的文本框旁边的图标,他们将选择所需的部门,当他们单击确定时,对话框将关闭,我将为我选择值更新文本框。

我已经完成了将对话框的所有者传递到对话框表单并让 OK 按钮单击事件进行正确更新的路线,但这迫使我对表单类型进行 DirectCast,然后我只能重用当前表单上的选择器。

我已经能够在构造函数中使用 ByRef 变量并成功更新了一个值,但它仅在构造函数中有效。如果我尝试将 ByRef 值分配给 Department Picker 类中的某个内部变量,则会丢失它的引用方面。这是附加到我的表单的基本代码:

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

有人可以告诉我我在这里缺少什么或不同的方法来实现这一点吗?

注意:代码示例在 VB.NET 中,但我也会接受任何 C# 答案。8^D

4

5 回答 5

4

在这种情况下,我通常要么

  • 编写一个 ShowDialog 函数来执行我想要的操作(例如返回值)或
  • 只需让结果成为对话框中的一个属性。这就是常见文件对话框在 BCL 中的操作方式。然后调用者必须读取属性以获取结果。在我看来这很好。

您还可以组合这些方法,方法是使结果值成为对话框中的属性并创建一个 ShowDialog 方法,该方法返回该属性值,可以根据需要作为 ByRef 或作为返回值,具体取决于您的需要。

例如,我会将其添加为使用说明(抱歉,这里没有 VB,您说欢迎使用 C#):

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

在对话框本身中,只需执行以下操作:

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

我没有在这个示例中使用新的 ShowDialog 实现。

于 2008-09-29T18:34:22.617 回答
0

问题是在构造函数中分配 TargetResult 是使用字符串作为参考。m_TargetResult 字符串只是 ref 字符串的副本,而不是对原始字符串的引用。

至于如何对原作“指针”,我不知道。

由于 VB.NET 不支持不安全的代码块,因此您无法对字符串进行指针引用,这使得这变得更加困难。

于 2008-09-29T18:35:32.427 回答
0

您可以将文本框引用传递给模态表单。

让用户选择任何部门。当用户单击确定时,将引用文本框的文本属性设置为所选部门的文本或 ID(取决于您的需要)

我正在使用您提供的代码。


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

于 2008-09-29T19:16:34.277 回答
0

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

注意:我没有测试过这个。我希望你明白我的意思。

OregonGhost:这样看起来更好吗?

用户可以调用 new DeptPicker().GetSelectedDepartment()。我不知道我不需要再次发布答案并且可以使用相同的帖子。

谢谢俄勒冈幽灵。现在,看起来还好吗?

于 2008-09-29T21:11:09.790 回答
0

这可能有效:

    // 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();
于 2008-09-30T18:44:49.057 回答