So I have a MainForm, in which I got a Panel.
To this I have created several UserControls that I will put in my Panel on request from different buttons.
My question is: I need to change the windowsize on MainForm depending on which UC I have in the Panel. How do I do this?
I was thinking of creating a public method in MainForm and then call it in the different UC on load, what do you think? Give me your best solutions. Thanks.
Edit: If this is to any help, this is in my MainUC-code to bring in other UC to replace MainUC in panel
private void UC1Button_Click(object sender, EventArgs e)
{
Panel MainPanel = MainForm.MainPanel;
if (!MainPanel.Controls.Contains(UC1.Instance))
{
MainPanel.Controls.Add(UC1.Instance);
UC1.Instance.Dock = DockStyle.Fill;
UC1.Instance.BringToFront();
}
else
{
UC1.Instance.BringToFront();
}
In each UserControl you can create an event which is triggered when content should change. For example you can create an event when a button is clicked
public partial class MyControl : UserControl
{
public event OnButtonClicked ButtonClicked;
public MyControl()
{
InitializeComponent();
}
private void MyButton_Click(object sender, EventArgs e)
{
if(ButtonClicked != null)
{
ButtonClicked((Button)sender);
}
}
}
public delegate void OnButtonClicked(Button button);
Then in your MainForm you can subscribe to events and change panel content and window size when appropriate.
public partial class MainForm : Form
{
MyControl myControl;
void Subscribe()
{
myControl.ButtonClicked += myControl_ButtonClicked;
}
void myControl_ButtonClicked(Button button)
{
// Change panel content
// Resize window
}
}
Related
I'm trying to make a button that shows a message box when you click it. The button is made as a user control and it's put inside a panel container. What i want to do is when you click the button, the controls dissapear within the panel.
Code in usercontrol
public partial class UserControl1 : UserControl
{
public event EventHandler ButtonClick;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//bubble the event up to the parent
if (this.ButtonClick != null)
this.ButtonClick(this, e);
MessageBox.Show("Test"); //test if the button itself is working
}
}
Code in Form
public partial class Form1 : Form
{
UserControl1 usercontrol1 = new UserControl1();
public Form1()
{
usercontrol1.ButtonClick += new EventHandler(btnIsClicked);
InitializeComponent();
}
private void btnIsClicked(object sender, EventArgs e)
{
panel1.Controls.Clear();
}
}
Having used the code above it's not working, the button works but nothing happens in the form.
I have main form and 2 usercontrols.The main form contains split container, In splitcontainer.panel1 i loaded UserControl1. In usercontrol different buttons are placed. I wants to load usercontrol2 on panel2(in main form) on button clicks which are placed inside the usercontrol1.
public partial class Form1 : Form
{
UserControl1 obj = new UserControl1();
public Form1()
{
InitializeComponent();
splitContainer1.Panel1.Controls.Add(obj);
}
}
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public event EventHandler ButtonClick;
public void button1_Click(object sender, EventArgs e)
{
}
}
On button1_Click i want to load UserControl2 on form splitcontainer panel2
You could change your UserControl1 like this:
public void button1_Click(object sender, EventArgs e)
{
if(ButtonClick != null)
ButtonClick(this, e);
}
And then in your Form1 constructor add the following code:
obj.ButtonClick += (Sender, e) =>
{
splitContainer1.Panel2.Controls.Add(obj2);
};
This should work
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.
I thought C# was hard. Try posting a question in stackoverflow.
I have a listbox and a button in a usercontrol, itself in a tabpage of a tabcontrol, itself on a form. I need to populate the listbox from the form when the button is clicked.
form > tabcontrol > tabpage > usercontrol > listbox & button
So, how do you notify the form that a deeply buried button has been clicked and then fill the listbox from the form (or call the usercontrol from the form to populate the listbox)?
Thank you guys.
Assuming that your question is about WinForms.
For notification:
Expose an event on the userControl and link it to the event of the button, form knows it's children.
public class MyUserControl {
private Button myButton;
public event EventHandler MyControlButtonClicked;
public MyUserControl() {
...
myButton.Click += OnMyButtonClicked;
}
private void OnMyButtonClicked(object sender, EventArgs arguments) {
if (MyControlButtonClicked != null) {
MyControlButtonClicked(this, arguments);
}
}
}
In your form:
public class MyForm {
private MyUserControl userControl;
public MyForm() {
...
userControl.MyControlButtonClicked += OnUserControlButtonClicked;
}
private void OnUserControlButtonClicked(object sender, EventArgs arguments) {
// handle the button click here
}
}
For population:
The same pattern, use your user control as a mediator. Add a public method on userControl that will do the listBox population and call it from your form.
I have Main Form which contains a Panel which loads different Usercontrol into the panel.
Now i need to access functions in the Main Form from the UserControl.
Below i have given my code;
This is my main Windows form class:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
loadlogin();
}
private void loadlogin()
{
login log = new login();
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
public void mytest()
{
}
}
As you can see i am loading a usercontrol to the mainPannel.
Now lets look at the usercontrol:
public partial class login : UserControl
{
string MyConString = "";
public login()
{
InitializeComponent();
}
public void button1_Click_1(object sender, EventArgs e)
{
//I want to call the parent function mytest(); HOW????
}
}
I want to access mytest() function when button1 us clicked. I have tried alot of other solution but i am still confused.
I have used:
Form my = this.FindForm();
my.Text = "asdasfasf";
This gives me reference to parent and i can change the form text but how can i access its functions???
Ok, the above answer will work but it is not good coding practice to pass in a "Parent Form" to a user control. UserControls should be located in a separate project from your forms project and your forms project should reference your control project in order to gain visiblity to them. Lets say for instance that you want this UserControl to be nested in another UserControl at some point. Your code no longer works without overloading the constructor. The better solution would be to use an event. I have provided an implementation using a CustomEventArg. By doing this, your login UserControl can sit on anything and still work. If the functionality to change the parents text is not requried, simply do not register with the event. Here is the code, hope this helps someone.
Here is the form code:
public Form1()
{
InitializeComponent();
loadlogin();
}
private void loadlogin()
{
login log = new login();
//Registers the UserControl event
log.changeParentTextWithCustomEvent += new EventHandler<TextChangedEventArgs>(log_changeParentTextWithCustomEvent);
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
private void log_changeParentTextWithCustomEvent(object sender, TextChangedEventArgs e)
{
this.Text = e.Text;
}
Here is the "login" UserControl code (in my test solution, just a userControl with a button)
public partial class login : UserControl
{
//Declare Event with CustomArgs
public event EventHandler<TextChangedEventArgs> changeParentTextWithCustomEvent;
private String customEventText = "Custom Events FTW!!!";
public login()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Check to see if the event is registered...
//If not then do not fire event
if (changeParentTextWithCustomEvent != null)
{
changeParentTextWithCustomEvent(sender, new TextChangedEventArgs(customEventText));
}
}
}
And finally, the CustomEventArgs class:
public class TextChangedEventArgs : EventArgs
{
private String text;
//Did not implement a "Set" so that the only way to give it the Text value is in the constructor
public String Text
{
get { return text; }
}
public TextChangedEventArgs(String theText)
: base()
{
text = theText;
}
}
Writing your controls in this fashion, with no visibility to Forms will allow your UserControls to be completely reusable and not bound to any type or kind of parent. Simply define the behaviors a UserControl can trigger and register them when necessary. I know this is an old post but hopefully this will help someone write better UserControls.
This may helps:
public partial class Form1 : Form
{
//Other codes
private void loadlogin()
{
login log = new login(this); //CHANGE HERE
mainPannel.Controls.Clear();
mainPannel.Controls.Add(log);
}
//Other codes
}
And
public partial class login : UserControl
{
Form1 _parent; //ADD THIS
public login(Form1 parent)
{
InitializeComponent();
this._parent = parent; //ADD THIS
}
public void button1_Click_1(object sender, EventArgs e)
{
this._parent.mytest(); //CALL WHAT YOU WANT
}
}
From your UserControl:
((Form1)Parent).mytest();