【问题】
在折腾:
的过程中,需要实现,在一个(子)窗体中,去设置另外一个(父)窗体中的值。
注:此处不需要获得另外窗口的值,因为之前已实现该功能了:
【已解决】C#中,如何在一个(子)窗体中,获得另一个(父)窗体中的(控件)变量的值
此处只是需要设置另外窗口中的变量值。
【解决过程】
1.本来打算用变量的形式,把父窗体指针传递给子窗体的,结果还是失败了:
【未解决】Cannot take the address of, get the size of, or declare a pointer to a managed type xxx
2.即使参考了微软官方的:
也只能实现代码:
public partial class completeHint : Form
{
private string curFullFilename;
private string curFolderPath;
private frmDownloadSongtasteMusic curParentForm;
public completeHint()
{
InitializeComponent();
}
//public unsafe void initParameter(IntPtr* parentForm, string fullFilename, string folderPath)
public void initParameter(string fullFilename, string folderPath)
{
//curFullFilename = fullFilename;
//curFolderPath = folderPath;
//curParentForm = (frmDownloadSongtasteMusic *)parentForm;
Control curParent = this.Parent;
Form foundParentForm = curParent.FindForm();
curParentForm = (frmDownloadSongtasteMusic)foundParentForm;
curParentForm.resetHintWindow();
}编译是没有错的,
但是运行时,由于this.Parent为null,所以无法获得所需要的窗体frmDownloadSongtasteMusic。
3.也试过,通过在父窗体frmDownloadSongtasteMusic中调用子窗体之前,通过:
//open hint window
if (hintWindow == null)
{
hintWindow = new completeHint();
}
hintWindow.Parent = this;
hintWindow.initParameter(curFullFilename, txbSaveTo.Text);
hintWindow.Show();的方式,去手动设置parent,结果出错:
Top-level control cannot be added to a control
所以还是行不通。
4.找了半天资料,都没有合适的。
后来是参考:
C# winfrom datagridview 子父窗口传值问题
去试试那个owner:
public partial class completeHint : Form
{
private string curFullFilename;
private string curFolderPath;
private frmDownloadSongtasteMusic curParentForm;
public completeHint()
{
InitializeComponent();
}
//public unsafe void initParameter(IntPtr* parentForm, string fullFilename, string folderPath)
public void initParameter(string fullFilename, string folderPath)
{
//curFullFilename = fullFilename;
//curFolderPath = folderPath;
//curParentForm = (frmDownloadSongtasteMusic *)parentForm;
//Control curParent = this.Parent;
//Form foundParentForm = curParent.FindForm();
//curParentForm = (frmDownloadSongtasteMusic)foundParentForm;
curParentForm = (frmDownloadSongtasteMusic)this.Owner;
curParentForm.resetHintWindow();
}结果竟然是owner也是null:
再试试手动赋值owner:
public void showCompleteHint()
{
//open hint window
if (hintWindow == null)
{
hintWindow = new completeHint();
}
//hintWindow.Parent = this;
hintWindow.Owner = this;
hintWindow.initParameter(curFullFilename, txbSaveTo.Text);然后:
//public unsafe void initParameter(IntPtr* parentForm, string fullFilename, string folderPath)
public void initParameter(string fullFilename, string folderPath)
{
//curFullFilename = fullFilename;
//curFolderPath = folderPath;
//curParentForm = (frmDownloadSongtasteMusic *)parentForm;
//Control curParent = this.Parent;
//Form foundParentForm = curParent.FindForm();
//curParentForm = (frmDownloadSongtasteMusic)foundParentForm;
curParentForm = (frmDownloadSongtasteMusic)this.Owner;
curParentForm.resetHintWindow();
}结果是可以正常获得owner的值的:
接下来,就可以正常的操作父窗体中的值和调用函数了。
【总结】
想要在子窗体中设置父窗体中的值,核心问题在于,在子窗体中,如何获得父窗体这个变量,此处的办法是,在父窗体调用显示子窗体之前,先设置子窗体的Owner为当前的自己self:
hintWindow.Owner = this;
然后子窗体中就可以通过获得Owner,再强制转换为父窗体类型的变量:
private frmDownloadSongtasteMusic curParentForm;
//public unsafe void initParameter(IntPtr* parentForm, string fullFilename, string folderPath)
public void initParameter(string fullFilename, string folderPath)
{
...
curParentForm = (frmDownloadSongtasteMusic)this.Owner;
}如此,获得了父窗体类型变量curParentForm后,就可以设置其值,调用其函数了。
【后记 2013-01-07】
后来,帮别人写类似的代码的时候,又参考了:
In C#, how can I change the properties of controls on another form?
解释的,比:
How to: Get a Value from Another Form
Changing a label’s text in another form in C#?
更清楚。
然后,参考其第二种方法,写出对应的代码,如下:
注:
- 此处要实现的:在Form2中拖动TrackBar,改变From1中的TrackBar的值,实现了两个窗体的TrackBar的值保持同步。
- 此处示例代码用的是TrackBar控件,需要.NET 3.5+
- Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace trackbarSetAnotherFormValue
{
public partial class Form1 : Form
{
//public TrackBar form1Trackbar; //把变量设置为public的方法不好
public Form1()
{
InitializeComponent();
}
//应该另外公开一个变量,用于读写对应的私有变量,才是好办法
public int currentTrackbarValue
{
get { return trackBar1.Value; }
set { trackBar1.Value = value; }
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.parentForm1 = this;
form2.Show();
}
private void Form1_Load(object sender, EventArgs e)
{
//form1Trackbar = trackBar1; //把变量设置为public的方法不好
}
}
}using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace trackbarSetAnotherFormValue
{
public partial class Form2 : Form
{
public Form1 parentForm1 = null;
public Form2()
{
InitializeComponent();
}
private void form2Trackbar_Scroll_1(object sender, EventArgs e)
{
parentForm1.currentTrackbarValue = form2Trackbar.Value;
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}
效果如下:
总体上说,还是有点麻烦的。。。


