从表单到另一表单的值 [英] Values from Form to another Form

查看:104
本文介绍了从表单到另一表单的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两种形式,我需要从另一种形式获取值:
示例1:
1.形式:

I have two forms and i need to get values from one to another:
Example 1:
1. form:

Ce cem = null;
        private void button2_Click(object sender, EventArgs e)
        {       
            if (cem == null || cem.IsDisposed)
            {
                cem = new Ce();
                cem.StartPosition = FormStartPosition.CenterScreen;
                cem.Show();
            }
            else
            {
                cem.BringToFront();
            }
}


关于2.形式:


on 2. form:

private void button1_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)this.Owner;
            if (radioButton1.Checked == true)
            {
                f1.comboBox4.Text = "First";
            }
            this.Close();
        }


我在行中得到错误:f1.comboBox4.Text ="First";它说:对象引用未设置为对象的实例.而且我没有将Ce中的文本发送到Form1上的comboBox4.

示例2:但是如果我使用此代码:
在1.表格上,我有:


i get the error in line: f1.comboBox4.Text = "First"; it says: Object reference not set to an instance of an object. And i don''t get that text from Ce to comboBox4 on Form1.

Example 2: But if i use this:
on 1. form i have:

private void button2_Click(object sender, EventArgs e)
        {
            Ce ce2 = new Ce();
            ce2.Show(this);
        }


并在2.形式上,我具有上面的代码:


and on 2. form i have the code just like above:

private void button1_Click(object sender, EventArgs e)
       {
           Form1 f1 = (Form1)this.Owner;
           if (radioButton1.Checked == true)
           {
               f1.comboBox4.Text = "First";
           }
           this.Close();
       }


在这种情况下是可行的,但是每单击一次button2(在窗体1上),它将一次又一次显示Ce.我想念什么吗?如何修复示例1或修改示例2,使其仅显示一种形式?
从具有不同形式的文本框中获取值的最简单方法是什么?


in this case works, but for every click on button2 (on Form 1) it will show form Ce again and again. Am i missing something? How to fix example 1 or modify example 2 so it will show only one form?
What is the easiest way to get values from textboxes that are on different forms?

推荐答案

您不会丢失任何东西.您确实一遍又一遍地显示了类Ce的形式.我不知道你为什么要这样做,但是你会的.请注意,您要这么做,而不是其他任何人. :-)

通常,这是关于表单协作的流行问题.最健壮的解决方案是在Form类中实现适当的接口,并传递接口引用而不是对Form的整个实例"的引用.请查看我过去的解决方案以获取更多详细信息:如何以两种形式在列表框之间复制所有项目 [ http://en.wikipedia.org/wiki/Accidental_complexity [ http://en.wikipedia.org/wiki/Loose_coupling [
You are not missing anything. You really show the form of the class Ce over and over. I have no idea why would you do such thing, but you do. Mind you, you do, not anyone else. :-)

Generally, this is the popular question about form collaboration. The most robust solution is implementation of an appropriate interface in form class and passing the interface reference instead of reference to a "whole instance" of a Form. Please see my past solution for more detail: How to copy all the items between listboxes in two forms[^].

Please also see other solutions in this discussion. If the application is simple enough, the solution could be as simple as declaring of some internal property in one form and passing a reference to the instance of one form to the instance of another form. For more complex projects, such violation of strictly encapsulated style and loose coupling could add up the the accidental complexity of the code and invite mistakes, so the well-encapsulated solution would be preferable.

Please see also:
http://en.wikipedia.org/wiki/Accidental_complexity[^],
http://en.wikipedia.org/wiki/Loose_coupling[^].

—SA


首先,我假设您有充分的理由希望将自己的表单"cem"设置为所有者".

您希望在显示/隐藏/关闭主窗体时显示/隐藏/关闭cem.

而且,您希望cem始终以可视方式显示在主窗体上方.这两个行为"就是Owner属性启用的用途:对于诸如查找和替换对话框以及要持久化的其他UI元素之类的东西非常有用. i>,但是与使用''ShowDialog不同,请勿阻止使用其余的应用程序.

简而言之:您想要一个事件...单击事件,单击"cem中的一个按钮...以对...中的ComboBox产生影响...我们假设是...您的主要类型" Form1".并且,仅当"RadioButton"被选中时,这种效果才会 发生.

您遇到的障碍是:即使您在运行时对表单所有者有有效的引用,也无法访问其私有
First, I assume you have a good reason for wanting to make your Form, ''cem, have an "Owner."

That you want ''cem to be shown/hidden/closed when the main Form is shown/hidden/closed.

And, that you want ''cem to always appear above the main Form visually. Those two "behaviors" are what the use of the ''Owner property enables: very useful for things like find-and-replace dialogues, and other UI elements you want to be persistent, but, unlike using ''ShowDialog, do not block using the rest of your Application.

In a nutshell: you want an Event ... a Click Event ... of a Button in ''cem to have an effect on a ComboBox in ... what we assume is ... your main Form of Type ''Form1. And, this effect will happen only when a certain RadioButton is "checked."

The road-block you''ve run into is the fact that: even if you have a valid reference to the Owner of a Form at run-time, you cannot access its private members using that reference.

There are many ways you can go about enabling "communication" between Forms. The general principle (separation of concerns, loose-coupling) that is best to follow is to create the minimum "dependency" between your Application''s Objects, to expose to one Object only what it needs to have, or needs to know, to perform specific tasks that require it to have access to some other Object.

Now it is logical, in this case, to claim that there is a hard-coded dependency between your Main Form and the Form ''cem: setting ''cem''s ''Owner property creates that behavioral dependency.

On a practical level, what all this means is that we want to be "stingy" with information: we want the Main Form to know only that something happened that requires a change in one of its UI elements; we want the ''cem Form to know "nothing" about "who created it," even though it does have this special relationship with the Main Form via the ''Owner property.

Okay, to bring all this "down to earth," let''s get coding:

1. define a private Method with no parameters that does not return a value in the Main Form
private void SetComboBox4()
{
    comboBox4.Text = "First";
}

2.在"cem表单定义"中,创建类型为"Action:

2. in the ''cem Form definition create a Public property of type ''Action:

public Action TheAction { set; get; }

3"的Public属性.当主表单创建"Ce表单"的实例时,我们将对"SetComboBox4方法"的引用注入到动作"类型在"cem中定义"的属性中:"

3. When the Main Form creates an instance of the ''Ce Form, we inject a reference to the ''SetComboBox4 method into the property of type ''Action defined in ''cem:"

public Form1()
{
    InitializeComponent();

    cem = new Ce();
    cem.TopLevel = true;
    cem.StartPosition = FormStartPosition.CenterScreen;
    cem.Owner = this;

    cem.TheAction = SetComboBox4;
}

Ce cem;

4.现在,在表单''cem中的Button ClickEventHandler中:

4. now, in the Button ClickEventHandler in Form ''cem:

private void button1_Click(object sender, EventArgs e)
{
    if (radioButton1.Checked)
    {
        TheAction();
    }

    this.Hide();
}

我们执行注入"到"cem"中的主窗体"中定义的方法.

如果您不熟悉使用.NET和FrameWork版本3.5(第一个Action 形式出现在.NET 2.0中)引入的.Action代理形式的概念,我鼓励您学习:[
^ ],[ ^ ].

学习使用''Action和''Func代表的投资非常值得您花时间,因为:它们是与Linq结合使用的非常强大的工具.

从技术上讲,当我们将对方法的引用注入到''cem实例中时:我们将 pointer 传递给方法''SetComboBox4.

最终结果如下:

主要形式:

We execute the method defined in the Main Form that we have "injected" into ''cem.

If you are new to the concepts of using the ''Action and ''Func forms of Delegates which came into .NET with FrameWork version 3.5 (the first form of Action<T> appeared in .NET 2.0), I encourage you to study: [^], [^], [^].

An investment in learning to use ''Action, and ''Func delegates is well worth your time because: they are very powerful tools used in combination with Linq.

Technically speaking, when we injected the reference to a method into an instance of ''cem: we passed a pointer to the method ''SetComboBox4.

Here''s the end result:

Main Form:

using System;
using System.Windows.Forms;

namespace TestTwoForms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            cem = new Ce();
            cem.TopLevel = true;
            cem.StartPosition = FormStartPosition.CenterScreen;
            cem.Owner = this;

            cem.TheAction = SetComboBox4;
        }

        Ce cem;

        private void button2_Click(object sender, EventArgs e)
        {
            if (! cem.Visible) cem.Visible = true;
        }

        private void SetComboBox4()
        {
            comboBox4.Text = "First";
        }
    }
}

形式"cem:

using System;
using System.Windows.Forms;

namespace TestTwoForms
{
    public partial class Ce : Form
    {
        public Ce()
        {
            InitializeComponent();
        }

        public Action TheAction { set; get; }

        private void button1_Click(object sender, EventArgs e)
        {
            if (radioButton1.Checked) TheAction();

            this.Hide();
        }
    }
}


我已经弄清楚了:因为我写了Ce cem = null;我不得不更改cem.Show()的行;到cem.Show(this);
1.形式:
I have figure it out: because i wrote Ce cem = null; i had to change the line from cem.Show(); to cem.Show(this);
1. form:
Ce cem = null;
        private void button2_Click(object sender, EventArgs e)
        {       
            if (cem == null || cem.IsDisposed)
            {
                cem = new Ce();
                cem.StartPosition = FormStartPosition.CenterScreen;
                cem.Show(this);
            }
            else
            {
                cem.BringToFront();
            }
}


现在就像魅力一样.


Now works like a charm.


这篇关于从表单到另一表单的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆