Reputation: 8636
Hi all I am having three forms in my application, my form1 will show some data from the database and I will have add/edit
buttons, corresponding to the option selected by user I will load Form2 and Form3. Now I would like to refresh the data on Form1
after user clicking on save on any of the forms Form2, Form3
Generally we write for one instance as follows
Form1 _Form1;
public Form2(Form1 frm)
{
_Form1 = frm;
}
private void button1_Click(object sender, EventArgs e)
{
_Form1.UpDateData();
}
But I need the same code to execute for different forms for suppose
Now in Form3
I need to implement the same scenario Instead of having the Form1
Caller in Form2
I need create instance for Form3
when this form was called is it possible
Form3 _Form3;
public Form2(Form3 frm)
{
_Form3 = frm;
}
private void button1_Click(object sender, EventArgs e)
{
_Form3.UpDateData();
}
I need to change the caller based on the form called
Upvotes: 1
Views: 384
Reputation: 121
You could use an delegate in a base form class.
//Declare public delegate
public delegate void CustomFormEvent(object sender);
// Create a base class
public partial class BaseUpdateForm : Form
{
public event CustomFormEvent UpdateData; // Event declaration
protected void CustomFormEventHandler()
{
if (this.UpdateData != null)
UpdateData(this);
}
}
Use the base class for as many forms as you would like, just register the event in the calling form or class (owner).
public partial class ChildForm1 : BaseUpdateForm
{
public ChildForm1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CustomFormEventHandler();
}
}
In the owner form where you want to use the reaised event:
private void button1_Click(object sender, EventArgs e)
{
// Form2 or Form3 in your example
ChildForm1 child1 = new ChildForm1();
child1.UpdateData += UpdateDataFormEvent;
child1.Show();
}
void UpdateDataFormEvent(object sender)
{
Form frm = sender as Form; // just cast it back to form
MessageBox.Show(frm.Text);
}
It is the custom event solution.
Regards.
Upvotes: 0
Reputation: 236208
Use DialogResult
of Form2
and Form3
to refresh items on Form1
:
// on Form1
using(var form2 = new Form2(item))
{
if (form2.ShowDialog() == DialogResult.OK)
{
// update items
}
}
On Form2
set it's DialogResult
property to DialogResult.OK
, DialogResult.Cancel
etc. according to user's action. E.g. when user deleted item, set result to DialogResult.OK
:
// on Form2
private void btnDelete_Click(object sender, EventArgs e)
{
// delete item from db
DialogResult = DialogResult.OK;
}
UPDATE - if you want to keep both forms opened, then you can't show Form2
as dialog, and code above will not work for you. You need to declare event of Form2
:
// on Form2
public event EventHandler<ItemDeletedEventArgs> ItemDeleted;
public Form2(List<Item> items)
{
...
}
private void btnDelete_Click(object sender, EventArgs e)
{
// delete item from db
OnItemDeleted(itemId)
}
protected void OnItemDeleted(int itemId)
{
if (ItemDeleted == null)
return;
ItemDeleted(this, new ItemDeletedEventArgs(itemId));
}
Subscribe to this event on Form1
:
private void form2_ItemDeleted(object sender, ItemDeletedEventArgs e)
{
int itemId = e.ItemId;
// update items
}
Where ItemDeletedEventArgs
is a custom class inherited from EventArgs
:
public class ItemDeletedEventArgs : EventArgs
{
public ItemDeletedEventArgs(int itemId);
{
ItemId = itemId;
}
public int ItemId { get; private set; }
}
If you don't want to follow all these Microsoft guidlines of events of type EventHandler
, arguments of type EventArgs
, then you can use simple event of type Action<int>
:
public event Action<int> ItemDeleted;
And raise it this way:
if (ItemDeleted != null)
ItemDelted(itemId);
Upvotes: 1
Reputation: 388
Why not use a publisher\subscriber pattern. So that Form1 is subscribing to events from Form2 and Form3, or vice-versa. It's a more decoupled and flexible solution.
Upvotes: 0
Reputation: 675
It sounds like you need an interface
public interface IUpdateData
{
void UpdateData();
}
//your forms will all implement the interface
public class Form2 : Form, IUpdateData
{
public void UpdateData()
{
//some implementation
}
}
public class Form3 : Form, IUpdateData
{
public void UpdateData()
{
//some implementation
}
}
Now back in your main form you accept instances of IUpdateData
IUpdateData _form;
public Form1(IUpdateData frm)
{
_form = frm;
}
Now in the click event you simply call your update data method
private void button1_Click(object sender, EventArgs e)
{
_form.UpdateData();
}
Upvotes: 2
Reputation: 2181
Use interfaces.
public interface IUpdateData
{
void UpdateData();
}
public class Form1 : Form, IUpdateData {...}
public class Form3 : Form, IUpdateData {...}
public class Form2 : Form
{
private IUpdateData _parentForm;
public Form2(IUpdateData _parentForm){...}
private void btnDelete_Click(object sender, EventArgs e)
{
_parentForm.UpdateData();
}
}
Or you can make a subsystem that allow to report data changes and allow to subscribe to recieve the changes.
Upvotes: 3
Reputation: 3967
you could do something like this
btnShowForm2.click(object sender, EventArgs e)
{
Form2 frm = new Form2();
DialogResult dr = frm.ShowDialog();
if(dr != DialogResult.OK)
return;
//call a method to update your data here
//this way you will reuse this with the other form
}
Upvotes: 0