我有一个显示父级(表单1)和子表单(表单2)的应用程序。在父级上,我单击一个调用第二个子窗体(窗体3)作为模式对话框的按钮。当我单击对话框窗体上的按钮时,它会使用对话框窗体中的文本更新父窗体上的tableLayoutPanel。我还需要它来更新第一个子窗体上的tableLayoutPanel并使用相同的信息。
对于父级和对话框表单,我使用此处提供的解决方案。 get value from child from to parent form
答案 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;
您可以做的其他事情(仍然很简单,但不是很好的选择,因为复杂性随着越来越多的表单互相交流而增加):
但是,您正在遇到可能在简单应用程序中工作的反模式(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中创建了一些水晶报表,重点在于报表,而不是用于驱动用户查看报表的对话框。
get,set通过与对话框用户不同的名称生成monthCalender的属性。您还可以将monthCalendar设为公开,但这是一种更实用的方法。关键是我想获得一个约会。实际来自日期的对象与对话框的用户无关,也没有对话框上有月份日历。