在TextChanged事件中将信息从一个打开的表单传递到另一个打开的表单

3

我还在学习C#,如果这是一个愚蠢的问题,请原谅我。另外,由于我不确定该如何表达,所以请原谅我的冗长。

我的场景:

我正在为我的应用程序使用DockPanel Suite,我有一个ParentForm、一个NotesForm和一个BrowserForm(实际上,我有几个其他类型的 BrowserForm,但如果我能让一个正常工作,我应该就能让其他的正常工作)

ParentForm在应用程序启动时加载,它加载了NotesForm,通过在ParentForm中点击按钮触发加载BrowserForm,然后该实例打开并保持打开状态,不会关闭。

因此,在我输入信息到NotesForm时,我已经有了所有三个窗体的建立实例。(我想那就是问题所在)

我的目标是将在NotesFormtextBox1中键入的信息传递到一个字符串变量中,称为notesText,该变量位于 BrowserForm 上,而无需在NotesForm上单击任何内容,我认为可能是通过TextChanged事件实现的。

目前,我能够使用属性(get、set)将信息传递到窗体上,但是我必须在NotesFormBrowserForm上单击一个按钮才能实现。

我包含了一种简化的代码,展示了我目前的做法。我的完整代码相当大,所以只是试图节省混淆并展示我正在进行的概念。

父窗体

public partial class parentForm : Form
{
    private notesForm notesForm = new notesForm();
    public parentForm()
    {
        InitializeComponent();

    }
    private void parentForm_Load(object sender, EventArgs e)
    {
        notesForm.Show(mainDock, DockState.DockLeft);

    }
    private void tb1_Click(object sender, EventArgs e)
    {
        BrowserForm.notesText= notesForm.passInfo;
    }

笔记表单

public partial class notesForm : DockContent
{
    private string _passInfo;
    public notesForm()
    {
        InitializeComponent();

    }
    public string passInfo
    {
        get { return textBox1.Text; }
        set
        {
            _passInfo = value;
            textBox1.Text = _passInfo;
        }
    }

}

浏览器表单

public partial class BrowserForm : DockContent
{
    private string passInfo;
    public BrowserForm()
    {
        InitializeComponent();

    }
            public string passInfo
    {
        get
        {
            return _passInfo;
        }
        set
        {
            _passInfo = value;
            notesText = _passInfo;
        }

    }
    string notesText;
    private void button1_Click(object sender, EventArgs e)
    {
    MessageBox.Show(notesText);
    }
    }

}

所以目前这个工作方式是可行的,但是为了让它工作,我必须在父表单上单击一个按钮,然后在浏览器表单上单击。理想情况下,我需要在你在笔记表单中输入文本框后将信息传递给浏览器表单。如果有帮助的话,输入到文本框中的信息是静态的,始终为9个数字字符(电话号码)。
另外,我的应用程序背景是什么?我用它来访问我们内部网络中的各种工具。它会自动登录并将其合并到一个应用程序中,而不是打开40-80个不同的浏览器窗口,最终(希望)从这些工具中自动提取一些信息,因此我们不必再搜索页面。 工具只是自动拉取。这并不是恶意行为,我也不是垃圾邮件发送者或其他任何东西,我为10家不同公司提供ISP技术支持,每家公司都有8-10个服务工具。
任何关于此事的帮助将不胜感激,或者如果有更简单的方法可以实现我所做的事情,我也很乐意听取意见。如果您想看到我的整个代码(如果有帮助),请告诉我,我不介意发布它,只是非常繁琐。

1
圣墙文本 本·阿弗莱克 - Jonesopolis
@Jonesy 哈哈,我知道抱歉了,可能有些过头了,但比那些毫无意义的烦人的短问题要好。 - Nabbic
2个回答

2

我希望您需要将信息从一个子表单传递到另一个子表单,如果我理解的不正确,请指出。

一种实现方法如下:

1. 创建以下接口:

public interface IDataContainer
{
     void SetData(String data);
}

2. 让你的parentForm实现你的接口:

public partial class parentForm : Form, IDataContainer

并在类形式中为该方法提供实现。这个简单的接口将使实现者能够为任何目的存储(字符串)数据。

在您的情况下,SetData 方法的实现将充当桥梁,连接 notesForm 和您的 BrowserForm,以一种干净的方式在表格之间传递数据:

public partial class parentForm : Form, IDataContainer
[...]

public void SetData(String dataComingFromOtherSource)
{
     this.browserFormInstance.passInfo = dataComingFromOtherSource;
}
[...]

3. 给每个子表单的构造函数添加一个类型为IDataContainer的参数,以便您可以传递对IDataContainer实现(即您的parentForm)的引用。这样做的好处是:

public partial class parentForm : Form
{
    private notesForm notesForm = null;

    public parentForm()
    {
        InitializeComponent();

        // Note that at this point you are instantiating
        // the child-form and you are passing a reference
        // to the `parentForm` so that you can pass information
        // to it, and from it to whatever other form you may
        // need, in an elegant way.
        this.notesForm = new notesForm(this);
    }

4. 最后,在 notesForm 中,放置设置数据到你的 container 的逻辑:

public partial class notesForm : DockContent
{
    // On runtime this will in fact the `parentForm` object instance.
    IDataContainer myDataContainerInstance = null;

    public notesForm(IDataContainer myDataContainerInstance) : base()
    {
        InitializeComponent();

        // Assign the reference so that you can use it later
        this.myDataContainerInstance = myDataContainerInstance;

        textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        this.myDataContainerInstance.SetData(textBox1.Text);
    }
}

注意: 有一个静态类/单例也是一种解决方案,而且更简单...


这太好了。这正是我一直在为我的整个程序寻找的东西。当你需要传递许多不同的窗体并且不同的实例一直让我很头疼,使用属性有点麻烦。我过去尝试过类似的事情,但无法正确地使其工作。非常感谢,我会今晚尝试实现它! - Nabbic
很高兴听到这个好消息 ;) 如果实现过程顺利,请告诉我们。 - Luis Quijada
1
啊哈,它成功了!!太棒了,谢谢!!现在基本上要以这种方式重新编写所有内容了,哈哈。虽然会很繁琐,但代码的理解会更清晰和容易。 - Nabbic
工作得很好,但是作为好奇心,如果我想在以后添加另一个文本框怎么办? - Nabbic
1
在这种情况下,为了支持控制器(即您的“parentForm”)中不同的行为,您可以更改方法“SetData”的签名以接受自定义类,比如说“MyInterchangeData”。在该类中,您可以添加两个属性,一个是数据本身(“Object data”),另一个可能是新的“Enum”类型(您需要声明),我们称之为“KindOfDataEnum”,并且字段为“KindOfDataEnum kindOfData”。然后,“parentForm”将根据接收到的“KindOfDataEnum”值来决定要执行什么操作。基本机制将保持不变。 - Luis Quijada

1

是的,您需要在NotesForm中挂钩TextChanged事件,像这样:

public partial class notesForm : DockContent
{
    public notesForm()
    {
        InitializeComponent();
        textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        // Get value of text box here and either pass it to the Browser form 
        // via its constructor or get an instance of the Browser form and use 
        // the set of a property in the Browser form to store the value 
        string theTextBoxValue = textBox1.Text;
    }
}

@ Karl 我相信这就是我正在寻找的(对事件没有太多经验)谢谢! 我该如何通过构造函数传递它? - Nabbic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接