I have been trying to figure this out for the better part of two days and have searched everywhere to find a solution, so if this is easily answered I apologize up front. Also, I am fairly new to c# and programming in general.
I have a form wherein one button creates a new usercontrol. This user control has a listview (for now, at some point I'm probably going to change this to a datagridview) that is updated with information from an Access database. When another button (Save) on the Form is clicked, information is added to the database. I would like for my UserControl to detect when the Save button is clicked and update the listview.
Below is a sample from my code, trimmed down to what I hope are the important bits.
Form stuff.
public partial class Form1 : Form
{
public event EventHandler saveClick;
public Form1()
{
InitializeComponent();
}
public void buttonSave_Click(object sender, EventArgs e)
{
//Stuff happens here that saves all input to the database
if (this.saveClick != null)
this.saveClick(this, e);
}
//Creates the UserControl TodayCallHistory as tch and expands Form1 window to accomodate the new control
private void butListShow_Click(object sender, EventArgs e)
{
if (!expanded)
{
expanded = true;
butListShow.Text = "\u25C0";
TodayCallHistory tch = new TodayCallHistory();
tch.Name = "tch";
tch.SetParentForm(this); //This was added per the answer below
List<int> pos = new List<int>();
foreach (Control x in this.Controls)
{
int right = x.Right;
pos.Add(right);
}
tch.Location = new System.Drawing.Point(pos.Max() + 10, 10);
formWidth = this.Width;
this.Width = this.Width + tch.Width + 10;
this.Controls.Add(tch);
}
else
{
expanded = false;
butListShow.Text = "\u25B6";
foreach (Control x in this.Controls)
{
if (x.Name == "tch")
this.Controls.Remove(x);
}
this.Width = formWidth;
}
}
}
UserControl stuff.
public partial class TodayCallHistory : UserControl
{
private Form1 frm = new Form1();
public TodayCallHistory()
{
InitializeComponent();
//frm.saveClick += new EventHandler(saveWasClicked); Removed based on answer below
}
//This following part was added per the marked answer below
public void SetParentForm(Form1 parent)
{
frm = parent;
frm.saveClick += new EventHandler(saveWasClicked);
}
private void saveWasClicked(object sender, EventArgs e)
{
refreshList();
}
private void refreshList()
{
//Sends query to database and then populates a listview with this information
}
}
When the Save button is clicked on the Form, nothing happens on the UserControl. Just a big ole pile of nothing. If anyone can tell me what I'm doing wrong or a better way to approach this, I would be extremely grateful! I can also post more of my code if I'm not sharing enough.
EDIT 1: I should also mention that this is a WinForm, written in c# using Visual Studio Express 2015 for Windows Desktop.
EDIT 2: Added my code for creating the UserControl when a button is clicked on Form1. The same button also removes the control. Basically I wanted to have an "expand window" (I have no idea what the actual term should be) feature as part of my Form1.
EDIT 3: Using Harrison Paine's (not sure how to tag a username) suggestion below, I added the SetParentForm method to the UserControl. Since my UserControl isn't created until the button click on Form1, I had to add the SetParentForm on Form1 after it was created.
Right after
tch.Name = "tch";
I added
tch.SetParentForm(this);
EDIT 4: So as to avoid creating a new Form1, I made the following changes.
Form1
public static event EventHandler saveClick; //Added static modifier
public void buttonSave_Click(object sender, EventArgs e)
{
//Stuff happens here that saves all input to the database
if (Form1.saveClick != null)
Form1.saveClick(this, e); //Changed this.saveClick to Form1.saveClick
}
private void butListShow_Click(object sender, EventArgs e)
{
tch.Parent = this; //All the other stuff from above, plus this now
}
I changed this.saveClick
to Form1.saveClick
since it is has the static modifier (I mostly guessed I had to do this and am still working on understanding exactly what 'static' does hah)
UserControl
public TodayCallHistory()
{
Form1.saveClick += new EventHandler(saveWasClicked);
InitializeComponent();
}
I removed the Form1 frm = new Form1();
as well as the entire SetParentForm
method.
For those wondering why I didn't just have the UserControl created and always there, with just a .Visible
set to True
or False
, I determined after much reading that the "better practice" is to create and destroy controls as you need them, especially if you have a lot of them on a form. If I'm completely off-base/insane on this, please let me know so I can take the easy way out :)
It looks like your TodayCallHistory
is creating its own Form1
and listening to an event on that object.
You need to pass in the actual Form1
that has the user control and then register the event handler on that object.
Something like this:
In TodayCallHistory.cs
:
public void SetParentForm(Form1 parent)
{
frm = parent;
frm.SaveClick += new EventHandler(saveWasClicked);
}
In Form1.cs
:
public Form1
{
InitializeComponent();
this.myTodayCallHistory.SetParentForm(this);
}
The issue stems from the following:
public partial class TodayCallHistory : UserControl
{
private Form1 frm = new Form1();
The Form1
created here is an entirely different object than the "original" one, whose save button you are clicking. Instead of creating a brand new object, you need to pass the original one in somehow. The SetParentForm()
method is just one way to do this.