C# C从将关闭的弹出窗体中获取变量
我用从主窗体创建的userControls数组填充了一个窗体。我需要能够从主窗体访问这个userControls数组,一旦按下按钮时关闭弹出窗口。如果我填写表单,然后在不关闭弹出窗口的情况下按下主表单上的按钮,则会显示值。但是,如果关闭弹出窗口,则值不存在。我的主窗体是静态的,所以我可以在其他窗体中使用它的变量 弹出窗口的代码:C# C从将关闭的弹出窗体中获取变量,c#,.net,winforms,user-controls,C#,.net,Winforms,User Controls,我用从主窗体创建的userControls数组填充了一个窗体。我需要能够从主窗体访问这个userControls数组,一旦按下按钮时关闭弹出窗口。如果我填写表单,然后在不关闭弹出窗口的情况下按下主表单上的按钮,则会显示值。但是,如果关闭弹出窗口,则值不存在。我的主窗体是静态的,所以我可以在其他窗体中使用它的变量 弹出窗口的代码: public ScanChannel[] controls; public ScanListSetup() { InitializeC
public ScanChannel[] controls;
public ScanListSetup()
{
InitializeComponent();
int numChans = Convert.ToInt32(Form1.Self.numChannels.Text);
controls = new ScanChannel[numChans];
// Create the UserControls
for(int i = 0; i < numChans; i++)
{
controls[i] = new ScanChannel();
}
// Place them
for (int i = 0; i < numChans; i++)
{
controls[i].Location = new Point(13,(35+25*(i)));
this.Controls.Add(controls[i]);
}
doneButton.Location = new Point(82, 35 + (25 * (numChans + 1)));
this.Size =new Size(280, 110 + (25 * (numChans + 1)));
}
private void doneButton_Click(object sender, EventArgs e)
{
Form1.Self.setChannelsToScan(controls);
}
因此,如果我在弹出窗体仍然打开的情况下单击scanButton,调试写线将输出正确的值。但是,如果在单击弹出窗体上的“完成”按钮后关闭窗体,调试writeLine将输出Test:而不输出其他内容
在此方面的任何帮助都将不胜感激。谢谢。您的问题本质上归结为将数据从辅助窗口(即“弹出式”窗口)发送到创建数据的主窗口。无论您使用的是Windows控件对象还是字符串之类的简单数据类型,这都无关紧要,因此我将使用一个简单的示例来说明如何处理这种情况 假设有一个主窗体,看起来像这样。它有一个打开的按钮和一个文本框 当您单击“打开”时,它将打开此辅助输入窗口,您的弹出窗口如下所示:
public delegate void DataTransfer(string data);
public delegate void DataTransfer(string data);
public partial class MainForm : Form
{
public DataTransfer transferDelegate;
InputForm inputForm = null;
public MainForm()
{
InitializeComponent();
transferDelegate += new DataTransfer(ReceiveInput);
}
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
private void BtnOpen_Click(object sender, EventArgs e)
{
inputForm = new InputForm(transferDelegate);
inputForm.Show();
}
}
public class DataToPass
{
public string TextBoxText { get; set; }
public string SomeOtherData { get; set; }
// Other stuff you want...
}
现在的想法是这样的。单击“打开”打开输入表单,让用户在文本框中输入一些文本。单击OK按钮后,它将关闭输入窗口,并在主窗口中显示用户输入的文本。记住,此时输入窗口关闭,这与您的情况相同
所以我会利用这个机会来实现这个目标。委托允许您在windows之间传输您想要的数据
在我的主要声明中,我将声明一个签名如下的公共代表:
public delegate void DataTransfer(string data);
public delegate void DataTransfer(string data);
public partial class MainForm : Form
{
public DataTransfer transferDelegate;
InputForm inputForm = null;
public MainForm()
{
InitializeComponent();
transferDelegate += new DataTransfer(ReceiveInput);
}
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
private void BtnOpen_Click(object sender, EventArgs e)
{
inputForm = new InputForm(transferDelegate);
inputForm.Show();
}
}
public class DataToPass
{
public string TextBoxText { get; set; }
public string SomeOtherData { get; set; }
// Other stuff you want...
}
也就是说,此委托表示一个接受单个字符串参数并具有void返回类型的方法。其思想是让辅助输入窗口在Main中“调用”一个方法,该方法接受一个字符串参数。因此,如果有一种方法可以让我们从输入调用驻留在Main中的方法,并传递一个字符串,那么我们可以在输入窗口中获取用户输入文本,并将其传递到主窗口。到目前为止和我在一起
现在,如果我在Main中编写一个这样的方法,并让它从输入中调用,那么应该可以实现我们的目标。这里,txtDisplay是主窗体中的文本框
为了实现这一点,我将以如下的主形式定义DataTransfer类型的委托,并向其注册ReceiveInput方法。您的主要表单代码应该如下所示:
public delegate void DataTransfer(string data);
public delegate void DataTransfer(string data);
public partial class MainForm : Form
{
public DataTransfer transferDelegate;
InputForm inputForm = null;
public MainForm()
{
InitializeComponent();
transferDelegate += new DataTransfer(ReceiveInput);
}
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
private void BtnOpen_Click(object sender, EventArgs e)
{
inputForm = new InputForm(transferDelegate);
inputForm.Show();
}
}
public class DataToPass
{
public string TextBoxText { get; set; }
public string SomeOtherData { get; set; }
// Other stuff you want...
}
BtnOpen是主窗体中的打开按钮,单击它时,它将委托传递给输入窗体,然后打开它。因此,我们需要相应地修改输入表单:
在这里,我们修改构造函数,使其接受DataTransfer类型的委托,并将其设置为相同类型的本地实例。然后,单击输入表单上的BtnOK,我们接收用户输入的文本,并将该文本传递给所述代理并调用它。”调用“”与在主窗体中调用方法相同。此时,您可以如上所示关闭输入窗口,并且仍然可以从主窗体访问用户输入字符串数据
您可以使用相同的方法,并且可以传递控件而不是字符串。但是,来回传递一组控件并不是最好的方法,因此理想情况下,您可以从弹出窗口中的这些控件中提取所需的数据,并且只传递所述数据,而不是整个控件
编辑:OP发布错误代码后
好的,这是你的问题。testUserControl类不是常规类,而是从UserControl派生的控制元素。否则,将使用GUI元素。您不应该使用GUI元素来传递数据。因为,当你控制arr[i].getText;,它试图从textItem获取文本,但textItem是一个TextBox控件,此时不存在,因为您关闭了窗口。请记住,您执行委托。仅调用一次,此时*必须将所有数据发送回主窗口*
您应该做的是,只需定义一个类来保存所有要传递到主节点的数据。例如,类似这样的事情:
public delegate void DataTransfer(string data);
public delegate void DataTransfer(string data);
public partial class MainForm : Form
{
public DataTransfer transferDelegate;
InputForm inputForm = null;
public MainForm()
{
InitializeComponent();
transferDelegate += new DataTransfer(ReceiveInput);
}
public void ReceiveInput(string data)
{
txtDisplay.Text = data;
}
private void BtnOpen_Click(object sender, EventArgs e)
{
inputForm = new InputForm(transferDelegate);
inputForm.Show();
}
}
public class DataToPass
{
public string TextBoxText { get; set; }
public string SomeOtherData { get; set; }
// Other stuff you want...
}
现在,不是传递testUserControl数组,而是传递DataToPass数组。这样,在主窗体中,您不必执行以下操作:
controlArr[i].getText();
相反,您只需执行以下操作:
controlArr[i].TextBoxText;
其中controlArr现在是DataToPass类型的数组
简单地说,传递从UserControl派生的控件不是一个好主意。只需创建一个能够保存所有要传递的数据的类,并将其传递回main一次。感谢您的回复。不幸的是,我仍然有同样的问题
尝试此操作后出现问题。如果我删除关闭并保持弹出窗口打开,我的主窗体可以访问数据。如果我关闭弹出窗口,它是空的。我检查并调用了ReceiveData函数,但这就像弹出窗口消失后一样;由于缺少更好的术语,因此在我的main中取消了对变量的引用。对不起,我没有很好地解释这个问题。我很感谢你的帮助。也许分享你的代码,你可以上传到github。因为这应该是可行的,所以在关闭弹出窗口之前,请调用该方法并将值传递给Main,此时打开或关闭弹出窗口并不重要。不幸的是,我无法按照公司政策发布我的代码。您认为问题可能是因为C中的数组是引用类型吗?因此,通过删除弹出表单,我正在删除被引用的数组。如果我只发送一个字符串而不是一个数组,它就可以正常工作。我根本无法调试一个看不见的代码。如果您不能按照公司政策共享代码,人们通常会创建一个模拟代码示例,在不共享实际代码的情况下复制问题;在C语言中,它创建一个引用。因此,当原始数据消失时,重复数据也消失了。如果您正在做类似的事情,请尝试使用某个数组=另一个数组;