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!!!!!!!!");
}
Related
I was reading similar questions about overloading eventhandlers by not using eventhandlers but delegates or by calling other functions from within the eventhandler. But I really can't see how I can bind the delegate to the custom control like I am binding ButtonClick in the code below. I have a form with let's say 10 custom controls. Each custom control has 5 buttons. The way I am passing the key presses from each button of each custom control is:
This is in my custom control's cs file (GlobalDebugMonitorControl.cs)
namespace GlobalDebugMonitor
{
public partial class GlobalDebugMonitorControl : UserControl
{
public GlobalDebugMonitorControl()
{
InitializeComponent();
}
public event EventHandler ButtonClick;
private void MultiControl_Click(object sender, EventArgs e)
{
if (this.ButtonClick != null)
this.ButtonClick(sender, e);//**How Do I put here both sender and this**
}
}
}
Then all the buttons in the custom control.designer.cs have something like this:
this.openFileBTN.Click += new System.EventHandler(this.MultiControl_Click);
this.editFilePathBTN.Click += new System.EventHandler(this.MultiControl_Click);
this.delControlBTN.Click += new System.EventHandler(this.MultiControl_Click);
this.addControlBTN.Click += new System.EventHandler(this.MultiControl_Click);
this.editCompanyNameBTN.Click += new System.EventHandler(this.MultiControl_Click);
And then in my form1
namespace GlobalDebugMonitor
{
public partial class Form1 : Form
{
protected void UserControl_ButtonClick(object sender, EventArgs e)
{
Button tempButton = (Button)sender;
GlobalDebugMonitorControl tempParentControl = (GlobalDebugMonitorControl)((tempButton.Parent).Parent).Parent;
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (string item in tempGlobalPaths)
{
GlobalDebugMonitorControl tempGDMcontrol = new GlobalDebugMonitorControl();
tempGDMcontrol.Name = item.Split(',')[0];
tempGDMcontrol.companyNameLBL.Text = item.Split(',')[0];
tempGDMcontrol.globalPathTXT.Text = item.Split(',')[1];
tempGDMcontrol.ButtonClick += new EventHandler(UserControl_ButtonClick);
flowLayoutPanel1.Controls.Add(tempGDMcontrol);
}
}
}
}
As you can see I create a tempButton by the sender to do some things based on which button was pressed of the 5 and by sender.parent.parent (the custom control is inside a table that is inside a flowlayout that is inside another panel etc)I finally reach the custom control that tells me which of the 10 custom controls had it's button pressed.
So the question is, is there a way to pass both the sender(button that was pressed) and the great grandfather (the custom control that owns the sender button)? I mean it works but this way I need to now how many "generations" I need to go up.
Thank you for reading me.
You could introduce your own type of EventArgs
public class CustomEventArgs : EventArgs
{
public GlobalDebugMonitorControl Control { get; set; }
public CustomEventArgs(GlobalDebugMonitorControl control)
{
this.Control = control;
}
}
and then change eventHandler to use it:
public event EventHandler<CustomEventArgs> ButtonClick;
so the calling code would be:
this.ButtonClick(sender, new CustomEventArgs(this));
and of course the implementer of the event:
protected void UserControl_ButtonClick(object sender, CustomEventArgs e)
{
Button tempButton = (Button)sender;
GlobalDebugMonitorControl tempParentControl = e.Control;
}
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'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 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.