Sammy581071

Hi,
I have an MDI application and I am trying to make one form refresh the other another open form
to clarify this better
Form1 has data pulled from a db and shown using a ListBoxControl
Form2 edits the same data
how can I have Form2 force Form1 to refresh the its own data
all I can find is using delegates and events but all examples are requiring one of the forms to open the other one which is not whats happening in this case.

Any help would be appreciated

Thanks



Re: Visual C# Language Delegates and events

Michael Letterle

I'm not sure delegates or events are required for what you're trying to do. I assume Form1 and Form2 are created by the same class, have a public method in Form1 that will refresh the listboxcontrol, have a public field in Form2 of type form1. You can assign the public field in Form2 to the instance of form1 and call form1's public refresh method from within form2.





Re: Visual C# Language Delegates and events

Sammy

Thanks for the response Michael,
My first thought was the same but I couldnt get it to work.
Yes both forms are created by the parent form. Form1 have a listbox which is populated thru a public void method called get GetDepartments()
in this method the listbox display and value members are bound to the field from the datatbase
I tried calling GetDepartments from form2 but I didnt see any changes "the new data did not show in the listbox" if I close Form1 and open it again the data is there.







Re: Visual C# Language Delegates and events

decyclone

Hi Sammy,

There are two ways I can think of through which your problem can be solved.

1) Use this.MdiParent.MdiChildren property which is Form[] array from any of the child form. Iterate through that array and find the other form you want may be by matching the Name property. And call some public method on it which causes it to refresh it's data. This way you tightly couple the forms.

2) Second way is create an event in the parent form and a public function which causes to raise that event. Now, if Form2 has data to refresh, and Form1 changes data, Form2 subscribes to the parent's event and Form1 after changing data calls the public method to cause the event to raise. So, Form2 updates data in the Form2_ParentEvent function or whatever function it used to subscribe to the parent's event.





Re: Visual C# Language Delegates and events

Sammy

Jay,
I can find out if form1 is opened using the MdiParent.MdiChildren and Application.OpenForms without any problem but the problem is when I call form1.GetData() from form2 nothing changes in form1.





Re: Visual C# Language Delegates and events

decyclone

Hi Sammy,

Can you supply some code snippets, or an example code to better understand the problem I faced the same problem in an application and I used both techniques and so I know they work. If you supply an example code of your scenario, I could find out where you are getting trouble...





Re: Visual C# Language Delegates and events

Sammy

Sure Jay,

The application is an MDI application frmMain is the parent form which opens all the forms thru a menu but for frmAdmin.

when the application loads user login the login form opens frmAdmin which has this method I am using to populate the ListBox control

It gets called on the form_load event

public void GetDepartments()

{

Department oDep = new Department();

dtDep = new DataTable();

dtDep= oDep.GetDepartments();

lstDepartments.DataSource = dtDep;

lstDepartments.DisplayMember = dtDep.Columns[0].ColumnName;

lstDepartments.ValueMember = dtDep.Columns[2].ColumnName;

}

now frmAddDepmgm is just a regular form where users can add/edit or delete departments

after a user deletes or edit the department I need frmAdmin to refresh the data in the listbox

I know I can not create frmAdmin and call GetDepartments() since its already open thats why I thought of an event or a delegate





Re: Visual C# Language Delegates and events

cutealien

You can either create a Department Facade class and add dtDep datatable there.. All add/edit/delete/view functionality should be there !! .. if Department class is providing add/edit/delete functionality then you can create wrapper to original functions and only make changes to the shared datatable dtDep..

For view functionality just return the datatable dtDep !!!

OR

from frmAdmin class, call something like this after every add/edit/delete operation!

Form[] col = this.Owner.OwnedForms;
for (int i = 0; i < col.Length; i++)
{
if (colIdea is frmAddDepmgmFormClass)
{
((frmAddDepmgmFormClass)colIdea).GetDepartments();
break;
}
}





Re: Visual C# Language Delegates and events

Sammy

Thanks Naveed,

You pointed me to the right direction.

frmMain is the MDI client

frmManageDeps is an MdiChild

frmAdmin is an MdiChild as well --> opens after the client logs in and it contains the ListBox which is populated with the data from the db using the department Class

This is the complete method in case someone else needs to use it, it is called from frmManageDeps after the department is added/edited/deleted

private void RefreshParent()

{

Form[] children = this.MdiParent.MdiChildren;

for (int i = 0; i < children.Length; i++)

{

if (childrenIdea is frmAdmin)

{

((frmAdmin)childrenIdea).GetDepartments();

}

}

}





Re: Visual C# Language Delegates and events

decyclone

Hi Sammy,

Sorry, I was off for the weekend.


Now, I decided to create a working example for you :

1) Parent Form
public partial class MdiParentForm : Form
{
public event EventHandler DataRefresh;

public MdiParentForm()
{
InitializeComponent();
}

private void Form6_Load(object sender, EventArgs e)
{
Form f = null;

f = new MdiChildUpdater();
f.MdiParent = this;
f.Show();

f = new MdiChildRefresher();
f.MdiParent = this;
f.Show();
}

public void RaiseDataRefreshEvent()
{
EventHandler temp = DataRefresh;
if (temp != null)
{
temp(null, EventArgs.Empty);
}
}
}

2) Child form that causes the update :

public partial class MdiChildUpdater : Form
{
public MdiChildUpdater()
{
InitializeComponent();
}

// Button button1 = new Button();
private void button1_Click(object sender, EventArgs e)
{
if (ParentForm != null && ParentForm is MdiParentForm)
{
MdiParentForm pf = ParentForm as MdiParentForm;
pf.RaiseDataRefreshEvent();
}
}
}

3) Child form that has to update :

public partial class MdiChildRefresher : Form
{
public MdiChildRefresher()
{
InitializeComponent();
}

private void Form8_Load(object sender, EventArgs e)
{
if (ParentForm != null && ParentForm is MdiParentForm)
{
MdiParentForm pf = ParentForm as MdiParentForm;
pf.DataRefresh += new EventHandler(pf_DataRefresh);
}
}

// TextBox textBox1 = new TextBox();
void pf_DataRefresh(object sender, EventArgs e)
{
textBox1.Text += "Data Refresh at " + DateTime.Now.ToLocalTime() + Environment.NewLine;
// TODO : Reload Data
}
}

Try this code. I tested it and it works. Just create a button on first child form and create a multi-line textbox on second child form.

After you run the program, clicking on Updater child form causes the Refresher form to update it's textbox.

I thinks this should solve your problem. Try to apply it in your application.