简体   繁体   English

如何从另一个子表单更新一个子表单

[英]How do I update a child form from another child form

I have an app that displays a parent (Form 1) and child form (Form 2). 我有一个显示父窗体(窗体1)和子窗体(窗体2)的应用程序。 On the parent I click a button that calls a second child form (Form 3) as a modal dialog. 在父级上,我单击一个按钮,该按钮调用第二个子窗体(窗体3)作为模式对话框。 When I click a button on the dialog form, it updates a tableLayoutPanel on the parent form with text from the dialog form . 当我单击对话框表单上的按钮时,它将使用对话框表单中的文本更新父表单上的tableLayoutPanel。 I need it to also update a tableLayoutPanel on the first child form with the same information. 我还需要它以相同的信息更新第一个子窗体上的tableLayoutPanel。

For the parent and dialog form I use the solution provided here. 对于父窗体和对话框窗体,我使用此处提供的解决方案。 get value from child from to parent form 从孩子那里获得价值,从父母那里获得价值

First, to answer your question directly , you can access any form with: 首先, 要直接回答您的问题 ,您可以通过以下方式访问任何表格:

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

In this example, Form1 is the class name of the form you want. 在此的示例Form1是所需的窗体的类名称。 OpenForms is a collection of forms owned by your application. OpenForms是您的应用程序拥有的表单的集合。 At this point you can access frmIWantThisForm.somePropertyOfTheForm; 此时,您可以访问frmIWantThisForm.somePropertyOfTheForm;

For example (after the code above which sets the form I want), I want to populate a string with the background color name of a listbox (for some reason I guess I'm just partial to the background color of that listbox): 例如(在上面的代码设置了我想要的表单之后),我想用一个列表框的背景色名称填充字符串(出于某种原因,我想我只是部分地使用了该列表框的背景色):

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

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

Other things you could do are (still simple, but not great options because complexity grows as increasing numbers of forms are talking to each other): 您可以做的其他事情 (仍然很简单,但不是很好的选择,因为随着表单数量的增加,复杂性也会增加):

  1. Assign the form to the Tag property of another form so that it has access to the calling form (not very clear). 将表单分配给另一个表单的Tag属性,以便它可以访问调用表单(不是很清楚)。 The tag property stores itself as an object, so you'll need to use casting again (like in my example above when I cast the control to a ListBox). tag属性将自身存储为一个对象,因此您需要再次使用强制类型转换(例如在上面的示例中,当我将控件强制转换为ListBox时)。
  2. Change the constructor or the dialogs you're calling so that you can pass in another form. 更改构造函数或要调用的对话框,以便您可以传递其他形式。 This option isn't too bad because it's at least easy to see where the data is going, but complexity still increases as you gain more forms. 这个选项还不错,因为至少可以很容易地看到数据的去向,但是随着表格的增加,复杂性仍然会增加。

Complicated (but better) Answer 复杂(但更好)答案

However, you're running into an anti-pattern ( scary coding, see Wiki definition ) style that will potentially work in a simple application, but the complexity will grow exponentially. 但是,您正在遇到一种反模式( 可怕的编码,请参阅Wiki定义 ),该样式可能会在简单的应用程序中起作用,但是复杂度将成倍增加。 Every form will be referencing every other form and updates to the code will get more and more complex. 每个表单都将引用其他所有表单,并且对代码的更新将变得越来越复杂。 Imagine making an update and suddenly you break several other pieces of code. 想象一下进行更新,然后突然您破坏了其他几段代码。

Instead, I recommend you separate the data model from your view / controller code. 相反,我建议您将数据模型视图 / 控制器代码分开。 When you start the application, load data into the controller. 启动应用程序时,将数据加载到控制器中。 When you exit, save back. 退出时,保存回来。 Perhaps eventually you'll do that more often. 也许最终您会更频繁地这样做。 Then, when you call a modal dialog, if it's for a piece of the model, pass in that part and have the dialog edit the model based on that data. 然后,当您调用模式对话框时,如果该对话框用于模型的一部分,请传入该部分,然后让对话框根据该数据编辑模型。 This way instead of updating controls all across your code, the next dialog you open simply opens and updates it's "view" based upon your model. 这样,您无需打开整个代码中的控件,而是打开并打开下一个对话框,并根据模型更新它的“视图”。

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;
}

There is additional work you can do to separate your code into conceptual segments, and while this goes far beyond the scope of the question, consider looking into MVC (Model View Controller) tutorials for this application. 您还可以做其他工作来将代码分成概念部分,尽管这超出了问题的范围,但请考虑研究此应用程序的MVC(模型视图控制器)教程。 Code Project has a tutorial to get you started . Code Project提供了一个入门指南

From this article, we have the following description of these concepts: 通过本文,我们对这些概念进行了以下描述:

  • The Model - This should take care of all the operations which deal with the data required (in other words the business logic) for the application, which is implementing the MVC model from now onwards will be referred to as by the MVC application. 模型-这应该处理所有处理应用程序所需数据(换句话说,业务逻辑)的操作,从现在开始实施MVC模型的应用程序将称为MVC应用程序。 The operations can mean reading, writing data into the database, getting information from remote machines via network, time consuming operations etc. The model should also inform the view about any changes to the data happening in the background. 这些操作可能意味着读取数据,将数据写入数据库,通过网络从远程计算机获取信息,耗时的操作等。模型还应告知视图有关后台发生的数据的任何更改。
  • The View - This component takes care of presenting the data to the user. 视图-该组件负责将数据呈现给用户。 With respect to the context of this article, ie, WinForms, the view class will be tied around with the Form which will be shown to the user. 关于本文的上下文,即WinForms,视图类将与将显示给用户的Form捆绑在一起。
  • The Controller - This is the center and important component of the MVC pattern as it ties the Model and View together. 控制器-这是MVC模式的中心和重要组成部分,因为它将模型和视图联系在一起。 The Model which manipulates the data and the View which presents the data to the user does not know the existence of each other or they interact directly with each other. 操作数据的模型和将数据呈现给用户的视图不知道彼此的存在,或者它们彼此直接交互。 It is the controller which acts as an intermediary and ties them together. 充当中介并将它们联系在一起的是控制器。 For example, the controller takes the input from the user such as a button click and informs the model to take appropriate action, if there should be an action that needs to be initiated to manipulate the project data. 例如,如果应该启动一个操作来操纵项目数据的操作,则控制器会从用户那里获取输入信息,例如单击按钮,并通知模型采取适当的操作。

Here's some additional reading on tight vs loose coupling. 这是有关耦合与松耦合的一些其他读物。 Tight coupling is when objects need to know a lot about each other, and loose coupling is when they do not need to know a lot. 紧密耦合是指对象之间相互了解很多,而松散耦合是指对象之间不需要了解很多。 The former is hard to maintain and update while the latter is generally preferred. 前者很难维护和更新,而后者通常是首选。

I am not claiming that what follows is for large scale applications, but for small applications following approach works fine : 我并不是说以下内容适用于大型应用程序,但是对于小型应用程序,以下方法可以正常工作:

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
}

the Date property of the dialog class is simple and straight forward : 对话框类的Date属性简单明了:

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

For not too complex GUI's and not too complex applications this works fine. 对于不太复杂的GUI和不太复杂的应用程序,这很好。 Of course some applications start simple and grow and grow and grow. 当然,某些应用程序从简单开始,然后逐渐增长。 But in my opinion you don't have to start with the big guns right from the start. 但是我认为您不必从一开始就从大手笔开始。

The code in question is a copy paste and then deleted some overhead from a real application so you can see some more stuff going on. 有问题的代码是复制粘贴,然后从实际应用程序中删除了一些开销,因此您可以看到更多的信息。 This app creates some crystal reports in .NET and the emphasis is really on the reports and not as such on the dialogs I use to drive the user towards the reports. 这个应用程序在.NET中创建了一些水晶报表,重点实际上是报表,而不是我用来驱动用户访问报表的对话框。

  • On line 1 I am instantiating the form and passing information via the constructor of the form. 在第1行中,我实例化表单并通过表单的构造函数传递信息。 The fact that this is a focusCell.... you have to make abstraction from that, you can pass anything that way to your dialog if you need to. 事实上,这是一个FocusCell...。您必须以此为基础进行抽象,您可以根据需要将任何方式传递给对话框。
  • The second line, I am updating the title of the dialog. 第二行,我正在更新对话框的标题。 It's pragmatic, it could also have been done in the constructor of the dialog. 这很实用,也可以在对话框的构造函数中完成。 In Sw there are a millions ways to achieve something. 在瑞士,有数百万种方法可以达成目标。
  • line 3 show the dialog 第3行显示对话框
  • line 5 take results from the dialog. 第5行从对话框中获取结果。

The get, set makes a property of the monthCalender, public via a different name to the user of the dialog. get,set通过与对话框用户不同的名称公开了monthCalender的属性。 You can also make the monthCalendar public, but that is a more pragmatic approach. 您还可以将monthCalendar公开,但这是一种更为实用的方法。 The point is that i want to obtain a date. 关键是我想获得一个日期。 Where the date actually comes from is of no concern of the user of the dialog nor that there is a monthcalender on the dialog. 对话框的用户不关心日期实际来自何处,对话框上也没有月历。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何关闭子表单和子表单的子表单? - How do I close a child form of a child form AND the child form? 如何从父窗体中的另一个datagridview更新子窗体的datagridview - How I can update a datagridview for child Form from another datagridview in a parent Form 从另一个子窗体打开子窗体并将 MDI 设置为父窗体 - 怎么办? - Opening a child form from another child form and set MDI to parent form - how to do? 如何从另一个子窗体中打开一个子窗体? - How to open a child form from another child form? 如何从另一个 MDI 子窗体打开 MDI 子窗体 - how to open a MDI child form from another MDI child form 如何从第三个表单的事件中将表单作为子表单加载到另一个表单中? - how to load a form into another form as child from an event of a third form? 如何在C#中将数据从子窗体的子窗体传递到父窗体? - How do I pass data from child of child form to parent form in C#? 如何将值从子表单传递回父表单? - How do I pass a value from a child back to the parent form? 如果从子窗体调用方法,如何设置值? - How do I set a value if a method is called from a child form? 如何在不改变表单背后的代码的情况下每秒动态更新表单中的子控件? - How do I dynamicaly update a child control within a form every second without changing the code behind the form?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM