【已解决】C#中,如何在一个(子)窗体中,设置另外一个(父)窗体中的值

【问题】

在折腾:

C#中如何在右下角添加提示窗口,用于显示打开文件和文件夹

的过程中,需要实现,在一个(子)窗体中,去设置另外一个(父)窗体中的值。

注:此处不需要获得另外窗口的值,因为之前已实现该功能了:

【已解决】C#中,如何在一个(子)窗体中,获得另一个(父)窗体中的(控件)变量的值

此处只是需要设置另外窗口中的变量值。

【解决过程】

1.本来打算用变量的形式,把父窗体指针传递给子窗体的,结果还是失败了:

【未解决】Cannot take the address of, get the size of, or declare a pointer to a managed type xxx

2.即使参考了微软官方的:

Control.Parent Property

也只能实现代码:

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

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 is also 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的值的:

can get owner value

接下来,就可以正常的操作父窗体中的值和调用函数了。

【总结】

想要在子窗体中设置父窗体中的值,核心问题在于,在子窗体中,如何获得父窗体这个变量,此处的办法是,在父窗体调用显示子窗体之前,先设置子窗体的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的方法不好
              }
          }
      }
  • Form2.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 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)
              {
      
              }
          }
      }

 

效果如下:

drag 2 can change 1

again eg show 2 change 1

 

总体上说,还是有点麻烦的。。。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量