如何将ByRef变量持久保存到.net winforms对话框表单中?
我正在创建一个"部门选择器"表单,该表单将与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();