I have this user control named ItemControl.
public partial class ItemControl : UserControl
{
public ModuloFramework.ItemSystem.Item Item { get; set; }
public ItemControl(ModuloFramework.ItemSystem.Item item)
{
Control.CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
Item = item;
}
private void ItemControl_Load(object sender, System.EventArgs e)
{
itemNameLabel.Text = Item.Name;
itemTypeLabel.Left = itemNameLabel.Right + 5;
itemTypeLabel.Text = Item.Type.ToString();
itemPriceLabel.Left = itemTypeLabel.Right + 5;
itemPriceLabel.Text = Item.Price.ToString();
itemDescriptionLabel.Text = Item.Description;
}
}
I have another form, just a test one ofc:
public partial class Form1 : Form
{
public List<ModuloFramework.ItemSystem.Item> Items { get; set; }
private Button EscapeButton { get; }
public Form1(List<ModuloFramework.ItemSystem.Item> items)
{
InitializeComponent();
Items = items;
EscapeButton = new Button()
{
Enabled = false,
Visible = false
};
EscapeButton.Click += (sender, args) => Close();
}
private void Form1_Load(object sender, EventArgs e)
{
this.CancelButton = EscapeButton;
int y = 0;
foreach (Item item in Items) {
ItemControl control = new ItemControl(item);
control.Left = 0;
control.Top = y;
y += control.Height + 3;
panel1.Controls.Add(control);
}
}
}
This is the context in which the form is called:
Task.Run(() =>
{
List<Item> items = new List<Item>()
{
TestItem.Item1,
TestItem.Item2
};
Form1 form = new Form1(items);
form.Show();
});
What happens when I try to run it, is that the Form1 instance opens, and it gets stuck, whereas the places where the user controls were supposed to be, it shows transparent space, showing the parts behind the it and the game form,
And after a couple of seconds, the form dies.
Reopening the form again causes the same bug
What am i doing wrong here?
Edit: Fixed code, showing it here in case someone wants to see an example of Erik's fix
List<Item> items = new List<Item>()
{
TestItem.Item1,
TestItem.Item2,
TestItem.Item1,
TestItem.Item2
};
Form1 form = new Form1(items);
form.Show();
Thread trd = new Thread(() =>
{
Application.Run(form);
});
You shouldn't create a form from a task. Forms have a message pump which can only operate on the thread they are created. This message pump handles input events, drawing events, etc.
When you run code using Task.Run it runs on a threadpool thread. This means that a thread is assigned to run the code, and once it's done that thread is returned to the threadpool and no longer runs any code. Since you're not explicitly running the message pump on that thread then no update events will get processed and the form will act like it's dead.
The simplest thing to do is to create and run the form on the same thread as all your other forms. Barring that, then you should use a Thread object to create the form and use Application.Run(myForm) on that thread so that its messages get processed.
Related
First of all i am kinda new to C# but i understand enough to work mostly alone.
Now i have a problem that i have for some time with Windows Forms.
I'm trying to create a new Instance of a class called "FiestaService" which includes some variables (string, string, Label, Button).
I want to insert label1 and loginBtn into FiestaService Login so i can call it inside SCStatusCheck().
With the current code it only tells me
a field initializer cannot reference the non-static field
at the label = label1 and the same for button = loginBtn.
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
public List<FiestaService> FS = new List<FiestaService>();
public FiestaService Login = new FiestaService() {
serviceDataName = "Crestia_Login",
serviceTextName = "Login",
label = label1, // this is the point where i am stuck with the label1
button = loginBtn // same
};
private void Main_Load(object sender, EventArgs e)
{
label1.Text = Login.serviceTextName;
FS.Add(Login);
//... here are some more of them
}
public void SCStatusCheck() // is called with a 2 seconds Timer inside the Main_Load method
{
foreach(var service in FS) {
ServiceController SC = new ServiceController(service.serviceDataName);
if (SC.Status.Equals(ServiceControllerStatus.Running)) {
service.label.BackColor = Color.LightGreen;
service.button.Text = "Stop";
}
}
}
}
public class FiestaService
{
public string serviceDataName;
public string serviceTextName;
public Label label;
public Button button;
}
The last thing i want to mention is that i did try it with
public static Main main = new Main();
and
public static FiestaService Login = new FiestaService() { ..., label = main.label1, button = main.loginBtn };
but after starting to debug it tells me
The object reference was not set to an object instance.
That "is" working ..kinda.. and i can call them with the Login FiestaService but the SCStatusCheck() method can't change anything related to the Label/Button.
Thanks for everyone! If you see anything that i could do much better than i did feel free to correct me!
..and yes i have already read some posts. However, none of them led to a suitable solution.
I think I see your problem - the labels/buttons are created on this line:
InitializeComponent();
So you should defer creating the FiestaService instances until after this. Maybe like this:
public FiestaService Login;
public Main()
{
InitializeComponent();
Login = new FiestaService() {
serviceDataName = "Crestia_Login",
serviceTextName = "Login",
label = label1, // this is the point where i am stuck with the label1
button = loginBtn // same
};
}
The way you have it, when you do this:
new FiestaService() {
It happens before the labels are created, so all you do is set them to null
Also, think how you can separate the data from the UI. It is not good practice to mix it up like this, but if it works and you are just learning, don't worry too much.
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.
I'm having trouble figuring out how to properly do this.
The basics is that i have 1 form which is used to fill out all kinds of data which i save in 2 lists. The 2nd form is one that is called via a menu option which displays an overview of all the current data. it is opened like so:
private void OpenOverviewForm()
{
Overview formOverview = new Overview();
for (int i = 0; i < callListNL.Count; i++)
{
ListViewItem item = new ListViewItem(callListNL[i].Opco);
item.SubItems.Add(callListNL[i].UserID);
item.SubItems.Add(callListNL[i].Email);
item.SubItems.Add(callListNL[i].Title);
formOverview.listView1Overview.Items.Add(item);
}
for (int i = 0; i < callListPL.Count; i++)
{
ListViewItem item = new ListViewItem(callListPL[i].Opco);
item.SubItems.Add(callListPL[i].UserID);
item.SubItems.Add(callListPL[i].Email);
item.SubItems.Add(callListPL[i].Title);
formOverview.listView1Overview.Items.Add(item);
}
formOverview.StartPosition = FormStartPosition.CenterScreen;
formOverview.Show();
}
In this new form, there is a listview with a list of all saved logs. And what i want is for the endusers to be able to doubleclick one of the entries, which will then close the 2nd form and display the data that they've selected on the first form. In order to do that, i need to be able to use the doubleclick event of the listview to provide the index of the item that they've doubleclicked to one of my functions that exist in the first form. However i can't find a way to get my function from Form1 recognised in my Form2.
I know it's possible with the following:
public partial class Overview : Form
{
public Overview()
{
InitializeComponent();
}
private void listView1Overview_DoubleClick(object sender, EventArgs e)
{
Form1 newform = new Form1();
newform.OverviewFormDisplay(listView1Overview.SelectedIndices[0]);
}
}
But as this code actually creates a completely new instance of my original form, i don't think that this is useable. Or am i wrong?
Create a variable of your main form instance
and add constructor of Overview with reference of Form1 as parameter
public partial class Overview : Form
{
private Form1 _mainForm;
public Overview(Form1 mainform) : this()
{
this._mainForm = mainForm;
}
private void listView1Overview_DoubleClick(object sender, EventArgs e)
{
this._mainForm.OverviewFormDisplay(listView1Overview.SelectedIndices[0]);
}
}
Then you can use all public properties and methods of Form1 instance inside your Overview form
When creating instance of Overview form, pass reference of main form to constructor
//.....this line must be in the Form1
Overview formOverview = new Overview(this);
//....
You can also resolve this with creating a Property to your Overview form:
public partial class Overview : Form
{
public Overview()
{
InitializeComponent();
}
private ListViewItem lvi;
public ListViewItem SelectedItem
{
get
{
return lvi;
}
set
{
lvi = value;
}
}
private void listView1Overview_DoubleClick(object sender, EventArgs e)
{
SelectedItem = listView1Overview.SelectedItems[0];
Close();
}
}
And you have to edit your code that creates formOverview to look like this:
private void OpenOverviewForm()
{
Overview formOverview = new Overview();
for (int i = 0; i < callListNL.Count; i++)
{
ListViewItem item = new ListViewItem(callListNL[i].Opco);
item.SubItems.Add(callListNL[i].UserID);
item.SubItems.Add(callListNL[i].Email);
item.SubItems.Add(callListNL[i].Title);
formOverview.listView1Overview.Items.Add(item);
}
for (int i = 0; i < callListPL.Count; i++)
{
ListViewItem item = new ListViewItem(callListPL[i].Opco);
item.SubItems.Add(callListPL[i].UserID);
item.SubItems.Add(callListPL[i].Email);
item.SubItems.Add(callListPL[i].Title);
formOverview.listView1Overview.Items.Add(item);
}
formOverview.StartPosition = FormStartPosition.CenterScreen;
formOverview.ShowDialog();
if (formOverview.SelectedItem != null)//just in case the user closes formOverview without double-clicking any item
{
OverviewFormDisplay(formOverview.SelectedItem);
}
}
Well probably this is not the best way to do this if you don't want your formOverview to close every time the user double-clicks an item to execute those functions you wanted, but it does the work. Hopefully helps :)
I have many controls in a window. Requirement is to know which control gets the focus from the lost focus event of a control.
Say, A Text box and it has the focus. Now I am clicking a button. while doing this, need to know that i am moving the focus to button from the Text box lost focus event.
So how could i achieve this..
This is what I did and its working for me
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
lostFocusControl = e.OldFocus;
}
private void PauseBttn_PreviewKeyDown(object sender, KeyEventArgs e)
{
/**invoke OnPreviewLostKeyboardFocus handller**/
}
Hope it will help
You can use FocusManager to handle this,
In your LostFocusEvent, Use FocusManager.GetFocusedElement()
uiElement.LostFocus+=(o,e)=>
{
var foo=FocusManager.GetFocusedElement();
}
The following class watches the FocusManager for changes in focus, it's a looped thread so you have to put up with the fact that it's running but when focus changes it will just raise an event letting you know what changed.
Just add these two classes to your project.
public class FocusNotifierEventArgs : EventArgs
{
public object OldObject { get; set; }
public object NewObject { get; set; }
}
public class FocusNotifier : IDisposable
{
public event EventHandler<FocusNotifierEventArgs> OnFocusChanged;
bool isDisposed;
Thread focusWatcher;
Dispatcher dispatcher;
DependencyObject inputScope;
int tickInterval;
public FocusNotifier(DependencyObject inputScope, int tickInterval = 10)
{
this.dispatcher = inputScope.Dispatcher;
this.inputScope = inputScope;
this.tickInterval = tickInterval;
focusWatcher = new Thread(new ThreadStart(FocusWatcherLoop))
{
Priority = ThreadPriority.BelowNormal,
Name = "FocusWatcher"
};
focusWatcher.Start();
}
IInputElement getCurrentFocus()
{
IInputElement results = null;
Monitor.Enter(focusWatcher);
dispatcher.BeginInvoke(new Action(() =>
{
Monitor.Enter(focusWatcher);
results = FocusManager.GetFocusedElement(inputScope);
Monitor.Pulse(focusWatcher);
Monitor.Exit(focusWatcher);
}));
Monitor.Wait(focusWatcher);
Monitor.Exit(focusWatcher);
return results;
}
void FocusWatcherLoop()
{
object oldObject = null;
while (!isDisposed)
{
var currentFocus = getCurrentFocus();
if (currentFocus != null)
{
if (OnFocusChanged != null)
dispatcher.BeginInvoke(OnFocusChanged, new object[]{ this, new FocusNotifierEventArgs()
{
OldObject = oldObject,
NewObject = currentFocus
}});
oldObject = currentFocus;
}
}
Thread.Sleep(tickInterval);
}
}
public void Dispose()
{
if (!isDisposed)
{
isDisposed = true;
}
}
}
Then in your code behind, create a new instance of the Focus Notifier class and hook on to it's OnFocusChanged event, remember to dispose it at the end or the thread will keep your app open.
public partial class MainWindow : Window
{
FocusNotifier focusNotifier;
public MainWindow()
{
InitializeComponent();
focusNotifier = new FocusNotifier(this);
focusNotifier.OnFocusChanged += focusNotifier_OnFocusChanged;
}
void focusNotifier_OnFocusChanged(object sender, FocusNotifierEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.OldObject);
System.Diagnostics.Debug.WriteLine(e.NewObject);
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
focusNotifier.Dispose();
base.OnClosing(e);
}
}
have you tried to register your controls to Control.LostFocus event and there you can check for Form.ActiveControl, to determine which control currently has the focus
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.