如何从其他子表单更新子表单

时间:2015-07-02 17:28:07

标签: c# forms winforms

我有一个显示父级(表单1)和子表单(表单2)的应用程序。在父级上,我单击一个调用第二个子窗体(窗体3)作为模式对话框的按钮。当我单击对话框窗体上的按钮时,它会使用对话框窗体中的文本更新父窗体上的tableLayoutPanel。我还需要它来更新第一个子窗体上的tableLayoutPanel并使用相同的信息。

对于父级和对话框表单,我使用此处提供的解决方案。 get value from child from to parent form

2 个答案:

答案 0 :(得分:3)

首先,直接回答您的问题,您可以访问任何表单:

Form frmIWantThisForm = System.Windows.Forms.Application.OpenForms.OfType<Form1>().First();

在此示例中,Form1是所需表单的类名。 OpenForms是您的应用程序拥有的表单集合。此时,您可以访问frmIWantThisForm.somePropertyOfTheForm;

例如(在上面的代码设置我想要的表格之后),我想用一个列表框的背景颜色名称填充一个字符串(出于某种原因,我想我只是偏向于背景颜色的那个列表框):

    //the 'true' causes a search of children as well:
    Control theControl = frmIWantThisForm.Controls.Find("listBox1",true).First();

    string bgColor = ((ListBox)theControl).BackColor.Name;

您可以做的其他事情(仍然很简单,但不是很好的选择,因为复杂性随着越来越多的表单互相交流而增加):

  1. 将表单分配给另一个表单的Tag属性,以便它可以访问调用表单(不是很清楚)。 tag属性将自己存储为一个对象,因此您需要再次使用强制转换(就像上面我将示例转换为ListBox时的示例一样)。
  2. 更改您正在调用的构造函数或对话框,以便您可以传入另一个表单。这个选项并不是太糟糕,因为它至少很容易看到数据的去向,但随着您获得更多表单,复杂性仍然会增加。
  3. 复杂(但更好)答案

    但是,您正在遇到可能在简单应用程序中工作的反模式(scary coding, see Wiki definition)样式,但复杂性将呈指数级增长。每个表单都将引用其他所有表单,对代码的更新将变得越来越复杂。想象一下,做一个更新,突然你打破了其他几段代码。

    相反,我建议您将数据模型视图 / 控制器代码分开。启动应用程序时,将数据加载到控制器中。退出时,请保存回来。也许最终你会更频繁地这样做。然后,当您调用模态对话框时,如果它是模型的一部分,则传入该部分并让对话框根据该数据编辑模型。通过这种方式,您可以打开下一个打开的对话框,然后更新它,即可查看&#34;根据您的模型。

    internal class MortgageAccounts
    {
        internal List<Mortgage> Mortgages = new List<Mortgage>();
    
        internal decimal ComputeAverageAmount()
        {
            decimal amount = 0;
            //code to compute
            return amount;
        }
    
        internal void Load()
        {
            //Here you load your data from a save file, 
            //database, or some other method of deserializing.
        }
    
        internal void Save()
        {
            //Here you save your data (serialize in some way)
        }
    }
    
    internal class Mortgage
    {
        internal int Id;
        internal decimal Amount;
    }
    

    您可以执行其他工作将代码分成概念段,虽然这远远超出了问题的范围,但请考虑查看此应用程序的MVC(模型视图控制器)教程。 Code Project has a tutorial to get you started

    从这篇文章中,我们对这些概念进行了以下描述:

      
        
    • 模型 - 这应该处理所有处理所需数据的操作(换句话说,业务逻辑)   应用程序,从现在开始实现MVC模型   将由MVC应用程序引用。这些操作意味着   阅读,将数据写入数据库,从中获取信息   通过网络远程机器,耗时的操作等模型   还应该告知有关数据发生变化的观点   背景。
    •   
    • 视图 - 此组件负责向用户显示数据。关于本文的上下文,即WinForms,   视图类将与将显示的表单绑定   给用户。
    •   
    • 控制器 - 这是MVC模式的中心和重要组成部分,因为它将模型和视图联系在一起。该模型   它操纵数据和将数据呈现给的视图   用户不知道彼此的存在或他们互动   彼此直接相处。它是作为一个控制器   中介并将他们联系在一起。例如,控制器需要   来自用户的输入,例如按钮单击并通知模型   如果应该有需要的行动,采取适当的行动   开始操纵项目数据。
    •   

    这里有一些关于tight vs loose耦合的额外阅读。紧密耦合是指对象需要彼此了解很多,松耦合是指他们不需要了解很多东西。前者难以维护和更新,而后者通常是首选。

答案 1 :(得分:2)

我并未声称以下内容适用于大规模应用程序,但对于小型应用程序,以下方法可以正常工作:

RitVerplaatsenForm dlg = new RitVerplaatsenForm(focusCell.Date.AddDays(rit<7?rit-1:0));
dlg.Text += string.Format("({0} records)",rows.Length);
if (dlg.ShowDialog() == DialogResult.OK)
{
     DateTime date = dlg.Date;
     //do stuff with the obtained date from the dialog
}

对话框类的Date属性简单明了:

public DateTime Date
{
    get
    {
        return this.monthCalendar1.SelectionStart;
    }
    set
    {
        monthCalendar1.SelectionStart = value;
    }
}

对于不太复杂的GUI而不是太复杂的应用程序,这很好用。 当然,一些应用程序从简单开始,不断发展壮大。但在我看来,你从一开始就不必从大枪开始。

有问题的代码是复制粘贴,然后从实际应用程序中删除了一些开销,这样你就可以看到更多的东西了。这个应用程序在.NET中创建了一些水晶报表,重点在于报表,而不是用于驱动用户查看报表的对话框。

  • 在第1行我实例化表单并通过表单的构造函数传递信息。事实上,这是一个focusCell ....你必须从中做出抽象,如果你需要,你可以将任何方式传递给你的对话框。
  • 第二行,我正在更新对话框的标题。它是实用的,它也可以在对话框的构造函数中完成。在Sw中,有数百种方法可以实现某些目标。
  • 第3行显示对话框
  • 第5行从对话框中获取结果。

get,set通过与对话框用户不同的名称生成monthCalender的属性。您还可以将monthCalendar设为公开,但这是一种更实用的方法。关键是我想获得一个约会。实际来自日期的对象与对话框的用户无关,也没有对话框上有月份日历。

相关问题