Reputation: 11
I have an app that displays a parent (Form 1) and child form (Form 2). On the parent I click a button that calls a second child form (Form 3) as a modal dialog. When I click a button on the dialog form, it updates a tableLayoutPanel on the parent form with text from the dialog form . I need it to also update a tableLayoutPanel on the first child form with the same information.
For the parent and dialog form I use the solution provided here. get value from child from to parent form
Upvotes: 0
Views: 1783
Reputation: 7447
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 :
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. 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.
The get, set makes a property of the monthCalender, public via a different name to the user of the dialog. You can also make the monthCalendar public, but that is a more pragmatic approach. 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.
Upvotes: 2
Reputation: 1719
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. OpenForms
is a collection of forms owned by your application. At this point you can access 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):
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. 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. Code Project has a tutorial to get you started.
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. 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, i.e., WinForms, the view class will be tied around with the Form which will be shown to the user.
- The Controller - This is the center and important component of the MVC pattern as it ties the Model and View together. 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.
Upvotes: 3