如何将ByRef变量持久保存到.net winforms对话框表单中?

时间:2020-03-06 14:53:19  来源:igfitidea点击:

我正在创建一个"部门选择器"表单,该表单将与Winforms应用程序的许多"主要"表单一起用作模式弹出表单。理想情况下,用户将单击文本框旁边的图标,该弹出框将弹出表格,他们将选择所需的部门,然后单击"确定",对话框将关闭,我将为我选择值使用更新文本框。

我已经通过将对话框的所有者传递到对话框表单中并让"确定"按钮单击事件进行了正确的更新来完成此路由,但这迫使我对表单类型执行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中,但是我也将使用所有Canswers。 8 ^ D

解决方案

在这种情况下,我通常或者

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

我们还可以组合这些方法,方法是将结果值设置为对话框中的一个属性,并创建一个ShowDialog方法,该方法根据需要将其值作为ByRef或者作为返回值返回该属性值。

我将其添加为用法说明,例如(对不起,这里没有VB,我们说的是Cis欢迎使用):

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实现。

问题在于在构造函数中分配TargetResult会将字符串用作引用。 m_TargetResult字符串只是引用字符串的副本,而不是对原始字符串的引用。

至于如何使"指针"指向原始内容,我不知道。

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

我们可以将文本框引用传递给模式形式。

让用户选择任何部门。当用户单击"确定"时,将引用的文本框的text属性设置为所选部门的文本或者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

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:这样看起来好点吗?

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

感谢OregonGhost。现在,看起来还好吗?

这可能起作用:

// 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();