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.
Related
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();
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
}
}
I have created a form with 5 static tabs and then created 5 separate forms that load in to them at Main form load. The first of these tabs has buttons on the form that I want to link to and show the corresponding tab when clicked.
The problem I'm having is that the buttons not being on the main form but a separate form don't have the options to switch to the corresponding tab on the main form.
I have tried the tabControl1.SelectedTab = tabPage2 stumped me for a couple of days this one any help much appreciated
As I understand your question, your problem is "How to communicate the button click on the sub form to the main form".
I'd suggest to declare events in your sub forms and catch these events in your main form. So a simplified example of a sub form could look like this:
public class SubForm : Form
{
// this is the event to register with from MainForm
public event EventHandler ButtonClicked;
// thread safe event invocator (standard pattern)
protected virtual void OnButtonClicked()
{
EventHandler handler = ButtonClicked;
if (handler != null) handler(this, EventArgs.Empty);
}
// your button handler
private void button1_Clicked(object sender, Eventargs e)
{
OnButtonClicked();
}
}
And in your main form you could do the following:
public class MainForm : Form
{
private SubForm _subForm1 = new SubForm();
private SubForm _subForm2 = new SubForm();
public MainForm()
{
InitializeComponents();
// more initializatino
_subForm1.ButtonClicked += subForm1_ButtonClicked;
_subForm2.ButtonClicked += subForm2_ButtonClicked;
}
private void subForm1_ButtonClicked(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage1;
}
private void subForm2_ButtonClicked(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage2;
}
And you can also think about using only one someSubForm_ButtonClicked handler and infer which tab to select via the sender argument, which will be the SubForm that raised the event.
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 am hosting a WPF usercontrol in winform. I am using WPF control Expander in WPF usercontrol(UserControl1). When i expand or collapse the expander my mainform should get notified. How to achive this?
I tried with the following options:
Declared a delegate and event in userconttol1 and tried to subscribe in mainform - doesn't help
used childchanged event in mainform
WPF usercontrol name - usercontrol1
Mainform Name - Form 1
hosted usercontrol in main form name - elementHost1
this.elementHost1.ChildChanged += new System.EventHandler<System.Windows.Forms.Integration.ChildChangedEventArgs>(this.elementHost1_ChildChanged);//form1 designer
private void elementHost1_ChildChanged(object sender, ChildChangedEventArgs e)
{
var ctr = (elementHost1.Child as UserControl1);
if (ctr == null)
return;
ctr.isCollapsed+=new UserControl1.expandedDel(ctr_isCollapsed);
}
void ctr_isCollapsed(object sender, System.Windows.RoutedEventArgs e)
{
throw new NotImplementedException();
}
This solution doesn't help me.
WPF usercontrol Winforms interop - handling WPF events in Winforms
Requirement: WPF usercontrol(UserControl1) contains Expander(expander1) and expander contains 3 radio buttons
and WPF usercontrl hosted in winform(Form1)
when radio button changed in usercontrol main form should get notifed and based on selection it should popup some controls in mainform
Code:in usercontrol1.xaml.cs
public delegate void ucRadioButtonHandler(object sender, **ucButtonEventArgs** e);
public event ucRadioButtonHandler onRadioButtonClick;
private void radioButton1_Checked(object sender, RoutedEventArgs e)
{
if (onRadioButtonClick != null)
{
onRadioButtonClick(sender, new ucButtonEventArgs());
}
}
ucButtonEventArgs is a class defined in same usercontrol.xaml.cs
public partial class ucButtonEventArgs : EventArgs
{
public ucButtonEventArgs()
{
}
}
Now in MainForm Form1
public Form1()
{
InitializeComponent();
userControl11.onRadioButtonClick += new WpfControlLibrary1.UserControl1.ucRadioButtonHandler(userControl11_onRadioButtonClick);
}
void userControl11_onRadioButtonClick(object sender, WpfControlLibrary1.ucButtonEventArgs e)
{
System.Windows.Controls.RadioButton rb = (System.Windows.Controls.RadioButton)sender;
MessageBox.Show(rb.Content + " Selected!!!!!!!!");
}