Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何访问另一个窗体的窗体控件?_C#_Winforms_Controls - Fatal编程技术网

C# 如何访问另一个窗体的窗体控件?

C# 如何访问另一个窗体的窗体控件?,c#,winforms,controls,C#,Winforms,Controls,我有两个表单类,其中一个有一个列表框。我需要为列表框的SelectedIndex属性设置一个setter,我想从第二个表单调用它 目前,我正在做以下工作: 表格1 public int MyListBoxSelectedIndex { set { lsbMyList.SelectedIndex = value; } } public partial class Form1 : Form { public Form1() { InitializeComp

我有两个
表单
类,其中一个有一个
列表框
。我需要为
列表框
SelectedIndex
属性设置一个setter,我想从第二个
表单
调用它

目前,我正在做以下工作:

表格1

public int MyListBoxSelectedIndex
{
     set { lsbMyList.SelectedIndex = value; }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 frm = new Form2(this);
        frm.Show();
    }

    public string LabelText
    {
        get { return Lbl.Text; }
        set { Lbl.Text = value; }
    }
}
表格2

private ControlForm mainForm; // form 1

public AddNewObjForm()
{
     InitializeComponent();
     mainForm = new ControlForm();           
}

public void SomeMethod()
{
     mainForm.MyListBoxSelectedIndex = -1;
}
public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private Form1 mainForm = null;
    public Form2(Form callingForm)
    {
        mainForm = callingForm as Form1; 
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.mainForm.LabelText = txtMessage.Text;
    }
}

这是最好的方法吗?

我通常使用单例设计模式来实现类似的功能。我将创建应用程序在singleton下运行的主窗体,然后创建我希望在其他区域中接触的窗体和控件的访问器。然后,其他表单可以获取指向它们想要修改的控件的指针,或者获取它们想要更改的应用程序主要部分中的数据


另一种方法是在不同的表单上设置事件以进行通信,并使用主表单作为排序中心,在应用程序中将事件消息从一个表单传递到另一个表单。

将它们设置为单例并不是一个完全坏的主意,但我个人不喜欢这样做。我宁愿把一种形式的引用传递给另一种形式。这里有一个例子

Form1触发Form2打开。Form2具有重载构造函数,该构造函数将调用表单作为参数,并向Form2成员提供其引用。这就解决了通信问题。例如,我在Form1中将Label属性公开为public,而在Form2中对其进行了修改

通过这种方法,你可以用不同的方式进行交流

//您的表格1

public int MyListBoxSelectedIndex
{
     set { lsbMyList.SelectedIndex = value; }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 frm = new Form2(this);
        frm.Show();
    }

    public string LabelText
    {
        get { return Lbl.Text; }
        set { Lbl.Text = value; }
    }
}
//你的表格2

private ControlForm mainForm; // form 1

public AddNewObjForm()
{
     InitializeComponent();
     mainForm = new ControlForm();           
}

public void SomeMethod()
{
     mainForm.MyListBoxSelectedIndex = -1;
}
public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private Form1 mainForm = null;
    public Form2(Form callingForm)
    {
        mainForm = callingForm as Form1; 
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.mainForm.LabelText = txtMessage.Text;
    }
}

(来源:)



(来源:)

访问表单控件,如下所示:

formname.controls[Index]
您可以强制转换为适当的控件类型,例如:

DataGridView dgv = (DataGridView) formname.Controls[Index];

很简单,首先您可以访问其他表单,如下所示: (假设您的另一个表单是
Form2


就是这样,您只需在
Form1

Form2
中写入
TextBox1
,如果您不想像Joe Dabones建议的那样循环使用“所有”控件,还有一种方法。 在Form2中创建一个函数,并从Form1中调用它

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    public void SetIndex(int value)
    {
        lsbMyList.SelectedIndex = value;
    }
}

public partial class Form1 : Form
{
    public Form2 frm;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        frm=new Form2();
        frm.Show();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm.SetIndex(Int.Parse(textBox1.Text));
    }
}

如果
子表单
想要访问
父表单

ParentForm
实例传递给
ChildForm
构造函数

public partial class ParentForm: Form
{
    public ParentForm()
    {
        InitializeComponent();
    }

    public string ParentProperty{get;set;}

    private void CreateChild()
    {
         var childForm = new ChildForm(this);
         childForm.Show();
    }
}

public partial class ChildForm : Form
{
    private ParentForm parentForm;

    public ChildForm(ParentForm parent)
    {
        InitializeComponent();

        parentForm = parent;
        parentForm.ParentProperty = "Value from Child";
    }   
}

你为什么不直接使用事件呢?这就是它们的用途,对象之间的通信没有紧密耦合。@Ed Swangren-这就是我建议它们的原因。这完全是一种选择,尽管它需要更多的时间来完成每个单独的事件,因为您需要添加新的挂钩,而单例几乎是一次性的。我个人最喜欢做的事情是将UI从应用程序的核心行为中抽象出来。这个核心就是单例,可以将事件附加到它。然后,所有UI只是核心中数据的视图。这使得撤销/重做行为变得容易得多。我认为撤销重做行为没有任何要求,我不同意你的说法,即设置事件是一项繁重的任务。单身往往是解决任何问题的蹩脚办法。我打算列出一些支持论点,但我在这里找到了一个很好的列表:form2f2=newform2();这将导致表单的新实例,您可能创建的任何更改都将应用于该新实例,而不是“其他”可见表单。