C# Passing values from one form to another open form - c#

I am learning the C# programming language and am making a Payroll program addon for SAP Business One. I have two forms and I want to pass a value from PayrollFormulaBuilder.cs to EarnDeductSetup.cs.
The PayrollFormulaBuilder is used by a user to generate a formula and is saved to a string. A user clicks on a calculator button on the EarnDeductSetup form in order to open up the PayrollFormulaBuilder form. The EarnDeductSetup form is still open but in the background. I want the generated formula to show on my EarnDeductSetup form (I have a textbox, txt_formula_template.Text) as soon as a user clicks on an 'Apply button on the PayrollFormulaBuilder form. i would also like for this PayrollFormulaBuilder form to close as soon as the apply button is pressed.
Right now, I am unable to show the generated formula on my EarnDeductSetup form
My Code: (EarnDeductSetupForm)
namespace EIM_Payroll_Application
{
public partial class EarnDeductSetupForm : Form
{
private SAPbobsCOM.Company company;
public string SAPCodePD { get; set; }
public EarnDeductSetupForm(SAPbobsCOM.Company co)
{
InitializeComponent();
this.company = co;
}
...
private void btn_calculator_Click(object sender, EventArgs e)
{
PayrollFormulaBuilder PC = new PayrollFormulaBuilder();
PC.ShowDialog();
}
...
if (rb_calculated_amt.Checked == true)
{
txt_formula_template.Text = SAPUtility._formulaVariable;
formulaTemplate = txt_formula_template.Text;
}
SAPUtility.cs
namespace Payroll.Util.Helpers
{
public static class SAPUtility
{
public static string _formulaVariable = String.Empty;
public static string variable
{
get { return _formulaVariable; }
set { _formulaVariable = value; }
}
...
PayrollFormulaBuilder.cs
private void btnApply_Click(object sender, EventArgs e)
{
SAPUtility._formulaVariable = formula_display.Text;
this.Close();
EarnDeductSetupForm.ActiveForm.ShowDialog();
}
My question is, how do I get this formula to show on my txt_formula_template.Text textbox on my EarnDeductSetupForm as soon as a user presses apply on the PayrollFormulaBuilder form?

Set the button in the parent form to internal, then use the parent or parentform property in the dialog to access it, by casting it to the parent for type (this should expose the internal button with intellisense). Call ShowDialog with "this" as parameter (no quotes).
Subscribe to events on the internal button the parent form, in the child dialog. And do your thing in the event handler.

Related

How do I retrieve a custom list from another form in a using block? [duplicate]

I have a main form (let's call it frmHireQuote) that is a child of a main MDI form (frmMainMDI), that shows another form (frmImportContact) via ShowDialog() when a button is clicked.
When the user clicks the 'OK' on frmImportContact, I want to pass a few string variables back to some text boxes on frmHireQuote.
Note that there could be multiple instances of frmHireQuote, it's obviously important that I get back to the instance that called this instance of frmImportContact.
What's the best method of doing this?
Create some public Properties on your sub-form like so
public string ReturnValue1 {get;set;}
public string ReturnValue2 {get;set;}
then set this inside your sub-form ok button click handler
private void btnOk_Click(object sender,EventArgs e)
{
this.ReturnValue1 = "Something";
this.ReturnValue2 = DateTime.Now.ToString(); //example
this.DialogResult = DialogResult.OK;
this.Close();
}
Then in your frmHireQuote form, when you open the sub-form
using (var form = new frmImportContact())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
string val = form.ReturnValue1; //values preserved after close
string dateString = form.ReturnValue2;
//Do something here with these values
//for example
this.txtSomething.Text = val;
}
}
Additionaly if you wish to cancel out of the sub-form you can just add a button to the form and set its DialogResult to Cancel and you can also set the CancelButton property of the form to said button - this will enable the escape key to cancel out of the form.
I normally create a static method on form/dialog, that I can call. This returns the success (OK-button) or failure, along with the values that needs to be filled in.
public class ResultFromFrmMain {
public DialogResult Result { get; set; }
public string Field1 { get; set; }
}
And on the form:
public static ResultFromFrmMain Execute() {
using (var f = new frmMain()) {
var result = new ResultFromFrmMain();
result.Result = f.ShowDialog();
if (result.Result == DialogResult.OK) {
// fill other values
}
return result;
}
}
To call your form;
public void MyEventToCallForm() {
var result = frmMain.Execute();
if (result.Result == DialogResult.OK) {
myTextBox.Text = result.Field1; // or something like that
}
}
Found another small problem with this code... or at least it was problematic when I tried to implement it.
The buttons in frmMain do not return a compatible value, using VS2010 I added the following and everything started working fine.
public static ResultFromFrmMain Execute() {
using (var f = new frmMain()) {
f.buttonOK.DialogResult = DialogResult.OK;
f.buttonCancel.DialogResult = DialogResult.Cancel;
var result = new ResultFromFrmMain();
result.Result = f.ShowDialog();
if (result.Result == DialogResult.OK) {
// fill other values
}
return result;
}
}
After adding the two button values, the dialog worked great!
Thanks for the example, it really helped.
delegates are the best option for sending data from one form to another.
public partial class frmImportContact : Form
{
public delegate void callback_data(string someData);
public event callback_data getData_CallBack;
private void button_Click(object sender, EventArgs e)
{
string myData = "Top Secret Data To Share";
getData_CallBack(myData);
}
}
public partial class frmHireQuote : Form
{
private void Button_Click(object sender, EventArgs e)
{
frmImportContact obj = new frmImportContact();
obj.getData_CallBack += getData;
}
private void getData(string someData)
{
MessageBox.Show("someData");
}
}
I just put into constructor something by reference, so the subform can change its value and main form can get new or modified object from subform.
If you want to pass data to form2 from form1 without passing like new form(sting "data");
Do like that
in form 1
using (Form2 form2= new Form2())
{
form2.ReturnValue1 = "lalala";
form2.ShowDialog();
}
in form 2 add
public string ReturnValue1 { get; set; }
private void form2_Load(object sender, EventArgs e)
{
MessageBox.Show(ReturnValue1);
}
Also you can use value in form1 like this if you want to swap something in form1
just in form1
textbox.Text =form2.ReturnValue1
I use MDI quite a lot, I like it much more (where it can be used) than multiple floating forms.
But to get the best from it you need to get to grips with your own events. It makes life so much easier for you.
A skeletal example.
Have your own interupt types,
//Clock, Stock and Accoubts represent the actual forms in
//the MDI application. When I have multiple copies of a form
//I also give them an ID, at the time they are created, then
//include that ID in the Args class.
public enum InteruptSource
{
IS_CLOCK = 0, IS_STOCKS, IS_ACCOUNTS
}
//This particular event type is time based,
//but you can add others to it, such as document
//based.
public enum EVInterupts
{
CI_NEWDAY = 0, CI_NEWMONTH, CI_NEWYEAR, CI_PAYDAY, CI_STOCKPAYOUT,
CI_STOCKIN, DO_NEWEMAIL, DO_SAVETOARCHIVE
}
Then your own Args type
public class ControlArgs
{
//MDI form source
public InteruptSource source { get; set; }
//Interrupt type
public EVInterupts clockInt { get; set; }
//in this case only a date is needed
//but normally I include optional data (as if a C UNION type)
//the form that responds to the event decides if
//the data is for it.
public DateTime date { get; set; }
//CI_STOCKIN
public StockClass inStock { get; set; }
}
Then use the delegate within your namespace, but outside of a class
namespace MyApplication
{
public delegate void StoreHandler(object sender, ControlArgs e);
public partial class Form1 : Form
{
//your main form
}
Now either manually or using the GUI, have the MDIparent respond to the events of the child forms.
But with your owr Args, you can reduce this to a single function. and you can have provision to interupt the interupts, good for debugging, but can be usefull in other ways too.
Just have al of your mdiparent event codes point to the one function,
calendar.Friday += new StoreHandler(MyEvents);
calendar.Saturday += new StoreHandler(MyEvents);
calendar.Sunday += new StoreHandler(MyEvents);
calendar.PayDay += new StoreHandler(MyEvents);
calendar.NewYear += new StoreHandler(MyEvents);
A simple switch mechanism is usually enough to pass events on to appropriate forms.
First you have to define attribute in form2(child) you will update this attribute in form2 and also from form1(parent) :
public string Response { get; set; }
private void OkButton_Click(object sender, EventArgs e)
{
Response = "ok";
}
private void CancelButton_Click(object sender, EventArgs e)
{
Response = "Cancel";
}
Calling of form2(child) from form1(parent):
using (Form2 formObject= new Form2() )
{
formObject.ShowDialog();
string result = formObject.Response;
//to update response of form2 after saving in result
formObject.Response="";
// do what ever with result...
MessageBox.Show("Response from form2: "+result);
}
I raise an event in the the form setting the value and subscribe to that event in the form(s) that need to deal with the value change.

C# How do i change a label text from another form

So i have 2 forms.
Form 1 is my main form, and form 2 is where I enter text in a textbox to be displayed on a label on form 1. Also the button to 'confirm' and actually change the entered text of my label is on form 2 which needs to stay that way.
for some reason this does not work.
Form 2 has a text-box and a button, when I press the button, it changes the string value of the designated string.
This string is linked to a label on form 1. the string is being changed so that is not the problem I confirmed this by a adding a button which pops up a message box showing the new string value.
While searching for an answer I found that is must be some sort of refreshing problem, I tried a lot of methods with no success. Only methods that did work where those who would put my button onto form 1 instead of 2.
I've been googling for 3 hours straight on how to fix this problem but either the methods don't work or they change my button from form 2 to my main form (form 1).
Please don't call me lazy I really can't find a method that works!
EDIT:
Code
GameScreen.cs
namespace _2pGame
{
public partial class GameScreen : Form
{
public GameScreen()
{
InitializeComponent();
P1NameLabel.Text = gm.P1Name;
P1ClassLabel.Text = gm.P1Class;
P2NameLabel.Text = gm.P2Name;
P2ClassLabel.Text = gm.P2Class;
}
private void PlayerInfoButton_Click(object sender, EventArgs e)
{
PlayerInfo playerinfoload = new PlayerInfo();
playerinfoload.Show();
}
}
}
PlayerInfo.cs
namespace _2pGame
{
public partial class PlayerInfo : Form
{
public PlayerInfo()
{
InitializeComponent();
}
public void ConfirmPlayerInfo_Click(object sender, EventArgs e)
{
gm.P1Class = P1ClassChoice.Text;
gm.P1Name = P1TextBox.Text;
gm.P2Class = P2ClassChoice.Text;
gm.P2Name = P2TextBox.Text;
}
}
}
Refs.cs
namespace _2pGame
{
public partial class gm
{
public static string
P1Class,
P2Class,
P1Name,
P2Name;
}
}
An approach to this very well know situation is through delegates....
In your PlayerInfo form declare
public partial class PlayerInfo : Form
{
// define the delegate type (a parameterless method that returns nothing)
public delegate void OnConfirmPlayer();
// declare a public variable of that delegate type
public OnConfirmPlayer PlayerConfirmed;
.....
public void ConfirmPlayerInfo_Click(object sender, EventArgs e)
{
gm.P1Class = P1ClassChoice.Text;
gm.P1Name = P1TextBox.Text;
gm.P2Class = P2ClassChoice.Text;
gm.P2Name = P2TextBox.Text;
// Check is someone is interested to be informed of this change
// If someone assign a value to the public delegate variable then
// you have to call that method to let the subscriber know
if (PlayerConfirmed != null)
PlayerConfirmed();
}
}
Then in your GameScreen form, just before showing the PlayerInfo form, set the public PlayerInfo.PlayerConfirmed to a method into the GameScreen form class
private void PlayerInfoButton_Click(object sender, EventArgs e)
{
PlayerInfo playerinfoload = new PlayerInfo();
// Subscribe to the notification from PlayerInfo instance
playerinfoload.PlayerConfirmed += PlayerHasBeenConfirmed;
playerinfoload.Show();
}
// Method that receives the notification from PlayerInfo
private void PlayerHasBeenConfirmed()
{
P1NameLabel.Text = gm.P1Name;
P1ClassLabel.Text = gm.P1Class;
P2NameLabel.Text = gm.P2Name;
P2ClassLabel.Text = gm.P2Class;
}
This approach has the advantage to avoid a coupling between the GameScreen and the PlayerInfo. No need to know inside the PlayerInfo the existance of a GameScreen form and the name of its properties. You just publish a delegate that a subscriber could register to be informed of the changes and let the subscriber acts on its own code.
You need a reference to your main form and assign the textbox values each time they need to be updated.
public partial class PlayerInfo : Form
{
private readonly GameScreen _main;
public PlayerInfo(GameScreen main)
{
_main = main;
InitializeComponent();
}
public void ConfirmPlayerInfo_Click(object sender, EventArgs e)
{
gm.P1Class = P1ClassChoice.Text;
gm.P1Name = P1TextBox.Text;
gm.P2Class = P2ClassChoice.Text;
gm.P2Name = P2TextBox.Text;
main.P1NameLabel.Text = gm.P1Name;
main.P1ClassLabel.Text = gm.P1Class;
main.P2NameLabel.Text = gm.P2Name;
main.P2ClassLabel.Text = gm.P2Class;
}
}
You also need to pass the reference when the PlayerInfo form is created
private void PlayerInfoButton_Click(object sender, EventArgs e)
{
PlayerInfo playerinfoload = new PlayerInfo(this); //pass ref to self
playerinfoload.Show();
}
Note that there are other better ways to do this, but this is the easiest that I can think of.
You can probably look at events or Mediator pattern if you want something better.

Keeping values of secondary Form

I have two Forms: MainForm and OptionsForm, wich has a button (OK) that applies the some changes on MainForm. When I open the OptionsForm for the first time everything is ok, with the default values.
After I make some changes and and click OK the options are applied but when I open the OptionsForm for the second time, I wanted to hold the previous values, not the default ones like its happening.
OptionsForm is opened through MainForm like this
OptionsForm formOptions = new OptionsForm();
if (formOptions.ShowDialog(this) == DialogResult.OK)
{
// etc..
}
//...
public string otherLabel
{
get { return formMainLabel.Text; }
set { formMainLabel.Text = value; }
}
In OptionsForm I have a NumericUpDown and want to hold its value
private MainForm mainForm = null;
public OptionsForm(Form callingForm)
{
mainForm = callingForm as MainForm;
InitializeComponent();
}
// ...
private void btnOK_Click(object sender, EventArgs e)
{
this.mainForm.someLabel= someBox.Value.ToString(); // NumericUpDown
this.mainForm.otherLabel = "abc"; //>>> Getting NullReferenceException
this.Close();
}
Now I can hold my settings but I'm getting a NullReferenceException. I tryed this but it's still not working. Any sugestion?
ShowDialog() was already made to support this. It is different from Show(), other than it being modal, it also prevents the form object from being disposed when the user closes it. So you can simply call ShowDialog() again, the controls keep their original values:
private OptionsForm options = new OptionsForm();
private void button1_Click(object sender, EventArgs e) {
if (options.ShowDialog(this) == DialogResult.OK) {
// etc..
}
}
protected override void OnFormClosed(FormClosedEventArgs e) {
options.Dispose();
base.OnFormClosed(e);
}
Well, you should pass these values to OptionsForm, feel free to write custom constructor for OpptionsForm and call it when you need.
One way to do it would be to just always keep a reference to your FormOptions and show the same instance rather than creating a new one every time. Or, if you don't want to do that, you can create an Options class that stores all of your options, which can then be stored and passed into any new instance you create thereafter. There's advantages and disadvantages to both so feel free to choose the option that best suits your needs.
public class MyOptions
{
public String StringOption { get; set; }
public int IntOption { get; set; }
}
Your FormOptions would then have a MyOptions property where you can set all of your options and retrieve them.
public class FormOptions : Form
{
...
private MyOptions _options;
public MyOptions Options
{
get { return _options;}
set
{
_options = value;
// Set the Form's control values accordingly.
}
}
...
}
And finally, you would call it like so in your code:
FormOptions optionsForm = new FormOptions();
MyOptions savedOptions = new MyOptions(); // Probably don't want to create a new instance every time but I'm sure you get the idea here.
optionsForm.Options = savedOptions;
optionsForm.ShowDialog();
// Get the new options after the form is closed.
savedOptions = optionsForm.Options;
if you just want to keep only one numeric up/down control's value, then just pass it as a parameter in the constructor..
public FormOptions(MainForm -mainFrm, int curNumericValue)
{
someBox.value = curNumericValue;
}
and instantiate the form with the value from the MainForm
private void button1_click(....)
{
FormOptions formOptions = new FormOptions(this, Convert.toInt32(someLabel.text));
formOptions.ShowDialog();
}
Why not just make use of the "Settings" that are available within the build properties, and WinForms itself? Just have your settings form populate itself with these variables, and "set" them when you click OK. Then have the MainForm refresh from these settings once the SettingsForm has fully closed. Easy, no mess, and no passing variables between forms.
Overview: http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx
SO Question covering Settings: Save Settings in a .NET Winforms Application
It also has the added bonus that the values will be saved between sessions of the application.
Seems like you are calling an instance of the options form from a click event like this:
button1_click(object sender, EventArgs e)
{
OptionsForm optForm = new OptionsForm();
optForm.showDialog();
}
You have to create variable for the options form class within the Mainform class, instantiate it there, or in the constructor, and only call the ShowDialog() or Show() method within the button_Click event. Like this:
partial class MainForm:Form
{
OptionsForm optForm;
............
............
public MainForm() //Constructor
{
initialiseComponent();
optForm = new OptionsForm();
........
}
.......
private button1_Click(object sender, EventArgs e)
{
optForm.Show(); // or ShowDialog()
}
}
and use this.hide() instead of this.close() in the options form.. or else the form gets disposed..

The concept of callbacks (C#)

Hi I have a form (Form A) which has a button "Add" which pops up a text-entering form (Form B). After you've entered the text in Form B, you press "OK" (btnOK). At this point I want Form A to get the text and do something with it.
From what I see I have two options:
1) Form A passes a function (delegate) to Form B which executes it in the btnOK_Click function.
2) I somehow register a method in Form A with the btnOK.Click event.
Am I on the correct track and can you think of any solutions to a similar problem that I can read because I get in trouble with static methods and events...
If Form B is a modal window, you could add a public string property to Form B.
When the user is closing Form B you could set the property to the text that was entered by the user. Then, back in Form A you could read the public property of Form B to get the text that the user entered.
Add a property to form B that is something like
public class FormB { ...
public string Text
{
get { return textBox.Text; }
}
...
}
If you show form b like follows:
FormB b = new FormB();
WPF: if (b.ShowDialog() != true) return;
Winforms: if (b.ShowDialog(this) != DialogResult.Ok) return;
string txt = b.Text;
So basically what is happening is you are showing the modal form b, where the user can enter text. Once the form is closed, b.ShowDialog will return from blocking. At that point, you can ask for b's Text property and retrieve the string. The Text property should be bound to b's textbox using some method.
If you don't want to show b modally, you can do this:
FormB b = new FormB();
b.Closed += new EventHandler(FormB_Closed);
b.Show();
private void FormB_Closed(object sender, EventArgs e)
{
string text = ((FormB)sender).Text;
... do something
}
A better solution would be to put a public property on Form B containing the text you need. Then, just access that property from Form A after Form B has exited.
I prefer #1 - passing a delegate is clean and simple
class BInputValues {
public String Field1 { get; set; }
//...
};
partial class FormB {
readonly Action<BInputValues> callback;
public FormB(Action<BInputValues> callback) {
this.callback = callback;
}
protected override void btnOK_Click(object sender, EventArgs e) {
callback(new BInputValues {
Field1 = Field1.Text,
//...
});
}
}
override void btnAdd_click() {
var formb = new FormB(args => {
// do something with args
});
formb.ShowModal();
}
You could also create a Subclass of Form...
public class FormWithResult : Form
{
protected object FormResult { get; set; }
public DialogResult ShowDialog(out object result)
{
DialogResult dr = ShowDialog();
result = FormResult;
return dr;
}
public DialogResult ShowDialog(out object result, IWin32Window win)
{
DialogResult dr = ShowDialog(win);
result = FormResult;
return dr;
}
public void Return(object result)
{
FormResult = result;
Close();
}
}
Then you can write this to Call a modal form and retrieve a result
popup p = new popup();
object result;
p.ShowDialog(out result);
MessageBox.Show((string)result);
And in your popup form you can either do:
FormResult = textBox1.Text;
Close();
OR
Return(textBox1.Text);
To Close the form and return the value.
Subclassing Form has drawbacks as well of course, but I'll throw this out as another solution.
As a side not, a generic version of this where you could Strongly type the return value would be much better if it weren't for this limitation at design time: Visual Studio 2008 Winform designer fails to load Form which inherits from generic class
If you wanted Asynchronous results obviously this would have to be tweaked. I assume you are using Modal popups.

How to return a value from a Form in C#?

I have a main form (let's call it frmHireQuote) that is a child of a main MDI form (frmMainMDI), that shows another form (frmImportContact) via ShowDialog() when a button is clicked.
When the user clicks the 'OK' on frmImportContact, I want to pass a few string variables back to some text boxes on frmHireQuote.
Note that there could be multiple instances of frmHireQuote, it's obviously important that I get back to the instance that called this instance of frmImportContact.
What's the best method of doing this?
Create some public Properties on your sub-form like so
public string ReturnValue1 {get;set;}
public string ReturnValue2 {get;set;}
then set this inside your sub-form ok button click handler
private void btnOk_Click(object sender,EventArgs e)
{
this.ReturnValue1 = "Something";
this.ReturnValue2 = DateTime.Now.ToString(); //example
this.DialogResult = DialogResult.OK;
this.Close();
}
Then in your frmHireQuote form, when you open the sub-form
using (var form = new frmImportContact())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
string val = form.ReturnValue1; //values preserved after close
string dateString = form.ReturnValue2;
//Do something here with these values
//for example
this.txtSomething.Text = val;
}
}
Additionaly if you wish to cancel out of the sub-form you can just add a button to the form and set its DialogResult to Cancel and you can also set the CancelButton property of the form to said button - this will enable the escape key to cancel out of the form.
I normally create a static method on form/dialog, that I can call. This returns the success (OK-button) or failure, along with the values that needs to be filled in.
public class ResultFromFrmMain {
public DialogResult Result { get; set; }
public string Field1 { get; set; }
}
And on the form:
public static ResultFromFrmMain Execute() {
using (var f = new frmMain()) {
var result = new ResultFromFrmMain();
result.Result = f.ShowDialog();
if (result.Result == DialogResult.OK) {
// fill other values
}
return result;
}
}
To call your form;
public void MyEventToCallForm() {
var result = frmMain.Execute();
if (result.Result == DialogResult.OK) {
myTextBox.Text = result.Field1; // or something like that
}
}
Found another small problem with this code... or at least it was problematic when I tried to implement it.
The buttons in frmMain do not return a compatible value, using VS2010 I added the following and everything started working fine.
public static ResultFromFrmMain Execute() {
using (var f = new frmMain()) {
f.buttonOK.DialogResult = DialogResult.OK;
f.buttonCancel.DialogResult = DialogResult.Cancel;
var result = new ResultFromFrmMain();
result.Result = f.ShowDialog();
if (result.Result == DialogResult.OK) {
// fill other values
}
return result;
}
}
After adding the two button values, the dialog worked great!
Thanks for the example, it really helped.
delegates are the best option for sending data from one form to another.
public partial class frmImportContact : Form
{
public delegate void callback_data(string someData);
public event callback_data getData_CallBack;
private void button_Click(object sender, EventArgs e)
{
string myData = "Top Secret Data To Share";
getData_CallBack(myData);
}
}
public partial class frmHireQuote : Form
{
private void Button_Click(object sender, EventArgs e)
{
frmImportContact obj = new frmImportContact();
obj.getData_CallBack += getData;
}
private void getData(string someData)
{
MessageBox.Show("someData");
}
}
I just put into constructor something by reference, so the subform can change its value and main form can get new or modified object from subform.
If you want to pass data to form2 from form1 without passing like new form(sting "data");
Do like that
in form 1
using (Form2 form2= new Form2())
{
form2.ReturnValue1 = "lalala";
form2.ShowDialog();
}
in form 2 add
public string ReturnValue1 { get; set; }
private void form2_Load(object sender, EventArgs e)
{
MessageBox.Show(ReturnValue1);
}
Also you can use value in form1 like this if you want to swap something in form1
just in form1
textbox.Text =form2.ReturnValue1
I use MDI quite a lot, I like it much more (where it can be used) than multiple floating forms.
But to get the best from it you need to get to grips with your own events. It makes life so much easier for you.
A skeletal example.
Have your own interupt types,
//Clock, Stock and Accoubts represent the actual forms in
//the MDI application. When I have multiple copies of a form
//I also give them an ID, at the time they are created, then
//include that ID in the Args class.
public enum InteruptSource
{
IS_CLOCK = 0, IS_STOCKS, IS_ACCOUNTS
}
//This particular event type is time based,
//but you can add others to it, such as document
//based.
public enum EVInterupts
{
CI_NEWDAY = 0, CI_NEWMONTH, CI_NEWYEAR, CI_PAYDAY, CI_STOCKPAYOUT,
CI_STOCKIN, DO_NEWEMAIL, DO_SAVETOARCHIVE
}
Then your own Args type
public class ControlArgs
{
//MDI form source
public InteruptSource source { get; set; }
//Interrupt type
public EVInterupts clockInt { get; set; }
//in this case only a date is needed
//but normally I include optional data (as if a C UNION type)
//the form that responds to the event decides if
//the data is for it.
public DateTime date { get; set; }
//CI_STOCKIN
public StockClass inStock { get; set; }
}
Then use the delegate within your namespace, but outside of a class
namespace MyApplication
{
public delegate void StoreHandler(object sender, ControlArgs e);
public partial class Form1 : Form
{
//your main form
}
Now either manually or using the GUI, have the MDIparent respond to the events of the child forms.
But with your owr Args, you can reduce this to a single function. and you can have provision to interupt the interupts, good for debugging, but can be usefull in other ways too.
Just have al of your mdiparent event codes point to the one function,
calendar.Friday += new StoreHandler(MyEvents);
calendar.Saturday += new StoreHandler(MyEvents);
calendar.Sunday += new StoreHandler(MyEvents);
calendar.PayDay += new StoreHandler(MyEvents);
calendar.NewYear += new StoreHandler(MyEvents);
A simple switch mechanism is usually enough to pass events on to appropriate forms.
First you have to define attribute in form2(child) you will update this attribute in form2 and also from form1(parent) :
public string Response { get; set; }
private void OkButton_Click(object sender, EventArgs e)
{
Response = "ok";
}
private void CancelButton_Click(object sender, EventArgs e)
{
Response = "Cancel";
}
Calling of form2(child) from form1(parent):
using (Form2 formObject= new Form2() )
{
formObject.ShowDialog();
string result = formObject.Response;
//to update response of form2 after saving in result
formObject.Response="";
// do what ever with result...
MessageBox.Show("Response from form2: "+result);
}
I raise an event in the the form setting the value and subscribe to that event in the form(s) that need to deal with the value change.

Categories

Resources