how to refresh parent winform from child winform? - c#

The parent Window Forms button mouse move event is getting correctly into the status bar label of the child window form ... but the opposite of that is not working means "the child window form button mouse move event is not getting displayed into the parent window form status bar label, please help

One of the good ways to do it is to use events in your child class:
First, declare the event:
public partial class ChildForm: Form
{
public event EventHandler ButtonClicked;
public ChildForm()
{
InitializeComponent();
}
}
Then call it in the button onClick method of the child form:
...
ButtonClicked?.Invoke();
...
if your onclick event is button_onclick then it would look like:
private void button_onclick(object sender, EventArgs e)
{
ButtonClicked?.Invoke();
}
and add your refresh login to this event when you declare this child form from your parent form:
var childForm = new ChildForm();
childForm.ButtonClicked += (e,args)=>{
//put the logic here
}
childForm.Show();

You could use a reference like this:
public partial class MainForm : Form
{
YourChildForm ycf = new YourChildForm(this);
ycf.Show();
}
And in your child form:
public partial class YourChildForm : Form
{
MainForm mf_ref
public YourChildForm(MainForm mf)
{
InitializeComponent();
mf_ref = mf;
}
}
Now you can access to every pubblic method on your mainform just using
mf_ref.SomeMethod();

Related

Winforms add tabPage from child form to parent form

I want to add new tabpage from other form in parent form.
My parent form is MainWindow and this form has TabControl.
I have child form ChildForm when i click on child form button i want to add new tabpage in TabControl from MainWindow.
I try to create constructor dependency in ChildForm
private MainWindow mainWindow;
public List(MainWindow form)
{
this.mainWindow = form;
}
private void createButton_Click(object sender, EventArgs e)
{
TabPage tabPage = new TabPage("ASD");
mainWindow.MainTabControl.TabPages.Add(tabPage);
}
This will throw System.NullReferenceException!
I also try to create in MainWindow accessors witch will return mainTabControl access in MainWindow but also not work.
public static TabControl MainTabControl
{
get {
MainWindow self = new MainWindow();
return self.mainTabControl;
}
}
This not work becouse i create new reference and that is problem.
I try 2 examples and both not work and i know whay not work!!!
Anyone know any other opetion how to slove this problem ?
A better approach is leaving the task to create new tabpages to the MainWindow and do not let the child forms know anything of the internal details of the MainWindow. The child forms exposes an event and they will raise it when they want to notify their parent that it is time to create a new tabpage (or whatever the MainWindow wants to do). The MainWindow subscribes to this event and start the creation of the new tab page when requested to do so....
public class ListForm: Form
{
public delegate void OnNewTabPage(string key);
public event OnNewTabPage NewTabPage;
public ListForm()
{
.....
}
private void createButton_Click(object sender, EventArgs e)
{
// Here we pass to the subscriber of the event just a string as
// the delegate requires, but, of course, you could change this
// to whatever data you wish to pass to the mainwindow
// Event a reference to an instance of a class with many fields...
NewTabPage?.Invoke("ASD");
}
}
Code in main form
ListForm f = new ListForm();
f.NewTab += CreateTabPage;
f.Show();
private void CreateTabPage(string key)
{
TabPage page = new TabPage(key);
this.TabControl.TabPages.Add(page);
}

Passing a variable from Child Form to Parent Form

I'm using a container (mdi parent) to open up a main menu. The main menu allows the user to connect to a database and open other programs. I'm trying to display what database you are connected to on the container (parent form) but i'm having issues passing the string from main menu to the container. When the user clicks the connect button, I somehow need the container to have an event listener to listen for a button click from the child form. When the connect button is clicked on the child form, it will pass the variable to the parent. How would I go about doing this?
Maybe you can use an event. So each time the database name changes on the child form you can get a call back on the parent form
Child
public partial class Child : Form
{
public event DatabaseChangeHandler DatabaseChanged;
public delegate void DatabaseChangeHandler(string newDatabaseName);
public Child()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//When the database changes
if (this.DatabaseChanged != null)
{
this.DatabaseChanged("The New Name");
}
}
}
Parent
public partial class Parent : Form
{
private Child childForm;
public Parent()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Open the child form
childForm = new Child();
childForm.DatabaseChanged += childForm_DatabaseChanged;
childForm.ShowDialog();
}
void childForm_DatabaseChanged(string newDatabaseName)
{
// This will get called everytime you call "DatabaseChanged" on child
label1.Text = newDatabaseName;
}
}
Just declare a public variable Eg: var1 in Form2 and on selection of rows from Grid assign the selected value to the Form2 public variable var1.
Then Once you close the Form2. You can access the values in Form1 by say you have a textbox in Form1 which should get the selected value from grid of Form2 by mentioning as
Form2 f2=new Form2();
TextBox1.Text=f2.var1;
Hope this helps

Add/Remove panel controls by clicking button on dynamically added usercontrol

I am new to c# windows forms and I'm trying to make a GUI that has two panels. The left panel is used to display dynamically added user controls that contain buttons. The right panel is used to display dynamically added usercontrols that contain other controls: textboxes, labels, comboboxes, buttons, etc.
I've created a form1 that has the two panels. I can successfully load both panels with different UserControl.cs content by using a menu that I've added to the top of the form. When I click a menu option, form1 buttonPanel is loaded with the appropriate buttonPanel.cs content and form1 mainPanel is loaded with the appropriate mainPanel.cs content. However, when I click the button that exists on buttonPanel.cs, I can't get form1 mainPanel to change it's content.
ie: WelcomeMenu.cs has a button called btnPage2 that should change mainPanel controls to show Page2.cs usercontrol instead of Welcome.cs usercontrol.
I want to be able to use in the button click handler on UserControl.cs:
mainPanel.Controls.Clear();
UserControl usrCtl = new UserControl();
Form1.mainPanel.Controls.Add(usrCtl);
My problem seems to be that WelcomeMenu.cs cannot see or access Form1 mainPanel.
Is there a way to make this work? Or am I trying to do this the wrong way?
My reason for this method is so I can load a new buttonPanel.cs usercontrol and mainPanel.cs usercontrol for each department and then be able to change mainPanel content for each button I click in the current buttonPanel. I'm trying to avoid creating a bunch of panels on Form1 and then hiding them and only making them visible when I need them.
Update:
buttonMenu.cs
{
{
public partial class ucWelcomeMenu : UserControl
public ucWelcomeMenu()
{
InitializeComponent();
}
private void btnPage2_Click(object sender, EventArgs e)
{
Form1.mainPanel.Controls.Clear();
ucWelcome frm = new ucWelcome();
Form1.mainPanel.Controls.Add(frm);
}
}
}
Form1.mainPanel.Controls.Add(frm) generates an error on Form1.mainPanel that states:
"An object reference is required for the non-static field, method, or property 'Form1.mainPanel'
UPDATE 2:
Ok. I've searched several different links and found some helpful information. However, I am still unable to fire an event from a button click in a dynamically added UserControl.cs. I have 2 panels on Form1. menuPanel and mainPanel. They are both set to Modifiers = Public.
Here is my Form1:
namespace TestUserControl
public partial class Form1 : Form
{
private ucWelcomeMenu welc = new ucWelcomeMenu();
public Form1()
{
InitializeComponent();
ucWelcomeMenu welcomeMenu = new ucWelcomeMenu();
menuPanel.Controls.Add(welcomeMenu);
welc.ButtonClick += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
MessageBox.Show("Yes");
}
}
}
And Here is my UserControl:
namespace TestUserControl.UserControls
public partial class ucWelcomeMenu : UserControl
{
public event EventHandler ButtonClick;
public ucWelcomeMenu()
{
InitializeComponent();
}
private void btnPage2_Click(object sender, EventArgs e)
{
if (ButtonClick != null)
ButtonClick(sender, e);
}
}
}
Ok. I am definitely a little slow. I found my problem. I was Instantiating the ucWelcomeMenu twice. Once I removed the private instantiation above the constructor, the event fired just fine. Thanks for all the input. It sent me to some good links with some very helpful information.
Here is what I ended up with:
Form1 Menu Option Click Handler:
private void option1ToolStripMenuItem_Click(object sender, EventArgs e)
{
UserControl1 ctl1 = new UserControl1();
menuPanel.Controls.Add(ctl1);
ctl1.btn1Click += new EventHandler(btn1_Click);
UserControl2 ctl2 = new UserControl2();
mainPanel.Controls.Add(ctl2);
}
Button 1 Click Handler on Form1:
private void btn1_Click(object sender, EventArgs e)
{
mainPanel.Controls.Clear();
UserControl2 frm = new UserControl2();
mainPanel.Controls.Add(frm);
}
UserControl1.cs
public partial class UserControl1 : UserControl
{
public event EventHandler btn1Click;
public UserControl1()
{
InitializeComponent();
}
private void btn1_Click(object sender, EventArgs e)
{
if (btn1Click!= null)
btn1Click(sender, e);
}
}
Set the accessibility Modifiers property of mainPanel from private to internal public.

How to come back to parent form without creating new instance of parent class in C# windows application

How to come back to parent form without creating new instance of parent form in C# windows application?
I have tried this.Parent, this.MdiParent, this.MyParentForms but no one worked..
You can have a button in your parent form that is used to show another form. Add this code to the button's Click event:
//Click event of your button.
private void goToSecondForm_Click(object sender, EventArgs e)
{
this.Hide(); //Hides the parent form.
subform.ShowDialog(); //Shows the sub form.
this.Show(); //Shows the parent form again, after closing the sub form.
}
In your child form, add a public property with type of your parent form :
public class ChildForm:From
{
public ParentForm parent;
//...
}
Then, in your click event of showing child form, do this :
private void goToSecondForm_Click(object sender, EventArgs e)
{
this.Hide();
ChildForm child = new ChildForm();
child.parent = this;
//other stuff
child.Show();
}
At the end, in the FormClosing event of the child form, doing this :
private void Child_FormClosing(object sender, FormClosingEventArgs e)
{
this.parent.Show();
}
With this solution, if your parent form changes or updates, then you have the latest instance.

Using a control from the main form on subforms

My main form contains a TextBox control that will be used throughout the application as a notepad-like feature.
Some of the subforms that are called from the main form will share the Text property of the main form's TextBox, which will not be visible - only the ones in the subforms will.
I'm using an extended Form for each subform, and they are being called using ShowDialog().
What's the best way to "share" this text between all subforms and the main form?
Please forgive my broken English.
You can create a class having a public static property which points to some function, then use this property as method on other forms. You should initialize this property on the initialization of your main form.
E.g.
public class Utility
{
public static Action<string> SetNotePadValue
{
get;
set;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Utility.SetNotePadValue = (s) =>
{
// textBox1 is a control on this form
this.textBox1.AppendText(s + "\r\n");
};
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// this will set value in Form1's textBox1
Utility.SetNotePadValue("Some text");
}
}
What you're looking to do here is to create a new event on your form:
public class Form2 : Form
{
public event Action<string> TextChanged; //TODO consider renaming
private void button1_Click(object sender, EventArgs e)
{
var handler = TextChanged;
if(handler != null)
handler(textbox.Text);
}
}
The main form can then subscribe to this event when creating the form:
Form2 popup = new Form2();
popup.TextChanged += text => DoSomethingWithText(text);
popup.ShowDialog();

Categories