I have created custom control. I would like to perform in my custom control after that Form.Shown event. I have tried in Control.GotFocus event which has triggered before that Form.Shown event. I want to make the changes in my control after that Form.Shown event.
Is it possible? If yes means, please suggest me how to do this?
Thanks,
You could register to the event:
public class MyControl : UserControl
{
// you need a reference to the hosting Form
public MyControl(Form frmHost)
{
frmHost.Shown += FormHost_Shown;
}
private void FormHost_Shown(object sender, EventArgs e)
{
// Do your work
}
}
When you the create an instance of your control, just pass a reference to the hosting form:
this.Controls.Add(new MyControl(this));
If you need a parameterless constructor you could make the hosting Form a property of your control and set that property before the Shown event happens:
public class MyControl : UserControl
{
private Form frmHost;
public Form FrmHost
{
get
{
return frmHost;
}
set
{
frmHost = value;
frmHost.Shown += FormHost_Shown;
}
}
private void FormHost_Shown(object sender, EventArgs e)
{
// Do your work
}
}
public class MyForm : Form
{
public MyForm()
{
InitializeComponent();
// User control was created elsewhere (perhaps in the designer)
myUserControl.FrmHost = this;
}
}
No, the documented order of events when activating for the first time a windows forms is the following:
Control.HandleCreated
Control.BindingContextChanged
Form.Load
Control.VisibleChanged
Form.Activated
Form.Shown
As you can see, Shown is the last fired event. You would need to implement your own event in your custom base Form:
public event EventHandler AfterShwon;
protected override void OnShown(EventArgs e)
{
base.OnShow(e);
OnAfterShown(e);
}
protected virtual void OnAfterShown(e)
{
AfterShwon?.Invoke(this, e);
}
Related
I have a form with two controls A and B
, A has a key-down event and i show a message box when 'S' is pressed on A control.
And i want to show another message when 'S' is pressed in any other control.
how can I do this ?
Simply what I want is : I should be able to handle a Key-down event after all child controls.
and I should be able to know whether the Event is handle in a child control in Form-level Key-down.
I tried enabling Key-preview but when Key-preview is enabled Form-level event get's fired before child control events. I want child controls first, Then Form level one
I want form level Event to be fired after focused control's key down event is fired.
and I want to check in Form-level event whether the event is handled in focused controls key-down event.
What methods can I use for this ?
Please enlighten me.
you can do the following
here a sample code
Add new project call it EventSample
Add a UserControl call it AControl
Add a UserControl call it BControl
make the AControl BackColor Blue and BControl Red in order to
distinguish from the form
//Form1 code
namespace EventSample
{
public delegate void AfterChildEventHandler(Control control,Keys key);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
aControl1.OnChildFireEvent += OnChildFireEvent;
bControl1.OnChildFireEvent += OnChildFireEvent;
}
void OnChildFireEvent(Control control, Keys key)
{
MessageBox.Show("Form fired event from " + control.GetType().Name);
}
}
}
//AControl code
namespace EventSample
{
public partial class AControl : UserControl
{
public event AfterChildEventHandler OnChildFireEvent;
public AControl()
{
InitializeComponent();
}
private void AControl_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("A Control fired Key down");
if (OnChildFireEvent != null)
OnChildFireEvent(this, e.KeyCode);
}
}
}
//BControl code
public partial class BControl : UserControl
{
public event AfterChildEventHandler OnChildFireEvent;
public BControl()
{
InitializeComponent();
}
private void BControl_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("B Control fired Key down");
if (OnChildFireEvent != null)
OnChildFireEvent(this, e.KeyCode);
}
}
EDITED
another solution you can make it with less code
define a static event
handle this event inside the form
let each control to invoke this event
namespace EventSample
{
public delegate void AfterChildEventHandler(Control control, Keys key);
public class GlobalEvent
{
public static event AfterChildEventHandler OnChildEventFire;
public static void Invoke(Control control, Keys key)
{
if (OnChildEventFire != null)
OnChildEventFire(control, key);
}
}
}
changes in the A Control
namespace EventSample
{
public partial class AControl : UserControl
{
public AControl()
{
InitializeComponent();
}
private void AControl_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("A Control fired Key down");
GlobalEvent.Invoke(this, e.KeyCode);
}
}
}
changes in the B Control
namespace EventSample
{
public partial class BControl : UserControl
{
public BControl()
{
InitializeComponent();
}
private void BControl_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("B Control fired Key down");
GlobalEvent.Invoke(this, e.KeyCode);
}
}
}
Build the sample and run and try to press any key on A or B then you will find that A will fire then the form
hope it will help you
I have read through a lot of articles to resolve this problem, but I can't get this to work.
The Situation:
I have a WPF MainWindow where I am loading UserControls into it.
The Mainwindow should listen to an EventHandler in a Class called Navigation. The Event will be fired upon certain changes in the UserControls.
So far I can confirm that the UserControls can fire the Event, but the MainWindow does not pickup the Throw.
Navigation Class:
public class Navigation
{
public delegate void EventHandler(object sender, EventArgs args);
public event EventHandler ThrowEvent = delegate { };
public void NavigationUpdateEvent()
{
ThrowEvent(this, new EventArgs());
}
}
UserControl:
public delegate void EventHandler(object sender, EventArgs args);
public event EventHandler ThrowEvent = delegate { };
Navigation myNavigation = new Navigation();
public myUserControl()
{
InitializeComponent();
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
if (cbCheckBox.IsChecked.Value)
{
UMENavigation.NavigationUpdateEvent();
}
}
The MainWindow:
private void DoSomething()
{
MessageBox.Show("It worked!");
}
private Navigation _Thrower;
public MainWindow()
{
InitializeComponent();
_Thrower = new Navigation();
_Thrower.ThrowEvent += (sender, args) => { DoSomething(); };
}
However, the _Thrower never picks up the Fired Event..
Any help is greatly appreciated! This is starting to hurt :)
Greetings, Tom
Navigation instances in UserControl and in the MainWindow are different.
UserControl fires the event for its own instance. At the same time, MainWindow listens for the event from its own instance.
Either use single instance of Navigation, or create a proxy-event in UserControl and subscribe it in MainWindow.
Besides, you don't need to declare your EventHandler. It's already declared.
I have different controls in my usercontrols. And load usercontrols dynamically in my form
UserControl2 usercontrol = new UserControl2();
usercontrol.Tag = i;
usercontrol.Click += usercontrol_Click;
flowLayoutPanel1.Controls.Add(usercontrol);
private void usercontrol_Click(object sender, EventArgs e)
{
// handle event
}
The click event is not firing when I click a control in usercontrol. It only fires when I click on empty area of usercontrol.
Recurse through all the controls and wire up the Click() event of each to the same handler. From there call InvokeOnClick(). Now clicking on anything will fire the Click() event of the main UserControl:
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
WireAllControls(this);
}
private void WireAllControls(Control cont)
{
foreach (Control ctl in cont.Controls)
{
ctl.Click += ctl_Click;
if (ctl.HasChildren)
{
WireAllControls(ctl);
}
}
}
private void ctl_Click(object sender, EventArgs e)
{
this.InvokeOnClick(this, EventArgs.Empty);
}
}
This should solve your problem.
//Event Handler for dynamic controls
usercontrol.Click += new EventHandler(usercontrol_Click);
Take this:
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
Because events from ChildControls are not propagated to parents. So you have to handle Click event on every child control added to UserControl.
1-define a delegate at nameapace
public delegate void NavigationClick(int Code, string Title);
2-define a event from your delegate in UserControl class:
public event NavigationClick navigationClick;
3-write this code for your control event in UserControl:
private void btn_first_Click(object sender, EventArgs e)
{
navigationClick(101, "First");
}
4-in your Windows Form than use from your UserControl at Event add:
private void dataBaseNavigation1_navigationClick(int Code, string Title)
{
MessageBox.Show(Code + " " + Title);
}
I am really new to programming and currently working on a C# Windows Forms application.
The problem is the following:
I have a Form with different objects and controls like: tabpages, textboxes, timers, etc .
I also have a UserControl form which I load into one of the main Form's tabpages.
I would like to write a code into the UserControl , how can I manipulate element properties of the main Form.
For example: when I click on a button on the UserControl form It sets the main Form's timer.Enabled control to true.
It is possible to do this, but having the user control access and manipulate the form isn't the cleanest way - it would be better to have the user control raise an event and have the hosting form deal with the event. (e.g. on handling the button click, the form could enable/disable the timer, etc.)
That way you could use the user control in different ways for different forms if need be; and it makes it more obvious what is going on.
Update:
Within your user control, you can declare an event - In the button click, you raise the event:
namespace WindowsFormsApplication1
{
public partial class UserControl1 : UserControl
{
public event EventHandler OnButtonClicked;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = OnButtonClicked;
// if something is listening for this event, let let them know it has occurred
if (handler != null)
{
handler(this, new EventArgs());
}
}
}
}
Then within your form, add the user control. You can then hook into the event:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
userControl11.OnButtonClicked += userControl11_OnButtonClicked;
}
void userControl11_OnButtonClicked(object sender, EventArgs e)
{
MessageBox.Show("got here");
}
}
}
You may want to rethink what it is you are trying to accomplish. However, to answer your question, it can be done.
The best way to do it is to make a property in your UserControl called MainForm:
public Control MainForm {
get;
set;
}
Then, in your MainForm's Load event, set the property to itself:
userControl1.MainForm = this;
Finally, in your user control, set the MainForm's timer:
protected button_click(object sender, EventArgs e)
{
timerName = "timer1";
EnableTimer(timerName);
}
private void EnableTimer(timerName)
{
var timer = MainForm.Controls.FirstOrDefault(z => z.Name.ToLower().Equals(timerName.ToLower());
if (timer != null)
{
((Timer)timer).Enabled = true;
} else {
// Timer was not found
}
}
This is very simple. It's called events. On the user control you would expose an event with a EventHandler for the form to subscribe to.
public partial class MyUserControl : UserControl
{
/// You can name the event anything you want.
public event EventHandler ButtonSelected;
/// This bubbles the button selected event up to the form.
private void Button1_Clicked(object sender, EventArgs e)
{
if (this.ButtonSelected != null)
{
// You could pass your own custom arguments back to the form here.
this.ButtonSelected(this, e)
}
}
}
Now that we have the user control code we'll implement it in the form code. Probably in the constructor of the form you'll have some code like below.
MyUserControl ctrl = new MyUserControl();
ctrl.ButtonSelected += this.ButtonSelected_OnClick;
Finally in the form code you'll have a method that subscribed to the event like the below code that will set the Timer enabled to true.
private void ButtonSelected_OnClick(object sender, EventArgs e)
{
this.Timer1.Enabled = true;
}
And that's how you allow an event on a user control on a form set an object on the form.
You can set the timer1.Modifiers property to "internal" and access it with an instance to Form1:
form1.timer1.Enabled = true;
You need to have an instance of your class Form1, not the class itself. For example:
// INVALID
Form1.timer1.Enabled = true;
// VALID
var form1 = Form1.ActiveForm;
form1.timer1.Enabled = true;
But this is not a very clean way to do this, you would rather use events as described in NDJ's answer.
You need to put the below code,
(`userControl11.OnButtonClicked += userControl11_OnButtonClicked;`)
in a separate file in Visual Studio. The other file is called 'Form1.Designer.cs', and can be found in the Solution Explorer pane under
Form1 >> Form1.cs >> Form1.Designer.cs.
Hope this helps!
I want to get the clicked event of a Button which is in my UserControl and I am adding that UserControl dynamically in my form. I want the event to be raised in the Form in which i am adding the UserControl. Please if anyone could suggest me proper way then it will be really very helpful.
You need to expose the event in your user control, then subscribe it when you add the user control to the form. e.g.:
public partial MyUserControl:Control
{
public event EventHandler ButtonClicked;
private void myButtonClick(object sender, EventArgs e)
{
if (this.ButtonClicked != null)
this.ButtonClicked(this, EventArgs.Empty);
}
}
public partial MyForm:Form
{
private void MethodWhereYouAddTheUserControl()
{
var myUC = new MyUserControl();
myUC += myUC_ButtonClicked;
// code where you add myUC to the form...
}
void myUC_ButtonClicked(object sender, EventArgs e)
{
// called when the button is clicked
}
}
I guess you're using Winforms referring to your title.
What you can do it to forward your Click event.
So in the ctor of your UserControl
public class MyUserControl
{
public event EventHandler MyClick;
private void OnMyClick()
{
if (this.MyClick != null)
this.MyClick(this, EventArgs.Empty);
}
public MyUserControl()
{
this.Click += (sender, e) => this.OnMyClick();
}
}
Add your own event to your custom user control.
Inside your customer user control, once you add the button, also attach your (internal) event handler that will then raise your own public event with some way to tell the event handler which button has been clicked (you'll most likely need your own delegate here).
Once that's done, your form can add its own event handler just like you add one to the standard controls.
Rereading your question, this might not be the exact structure (the button is fixed, but the user control is dynamically added?). In any way, it should be almost the same, it just differs where/when you add the event handler upon creation.
With one static button it's a lot easier to be done - assuming you're using Windows Forms:
In your custom user control:
public event EventHandler ButtonClicked; // this could be named differently obviously
...
public void Button_OnClick(object sender, EventArgs e) // this is the standard "on button click" event handler created using the form editor
{
if (ButtonClicked != null)
ButtonClicked(this, EventArgs.Empty);
}
In your form:
// create a new user control and add the event
MyControl ctl = new MyControl();
Controls.Add(ctl);
ctl.ButtonClicked += new EventHandler(Form_OnUserControlButtonClicked); // name of the event handler in your form that's called once you click the button
...
private void Form_OnUserControlbuttonClicked(object sender EventArgs e)
{
// do whatever should happen once you click the button
}
when you are adding your usercontrol to your form, register the click event (if it is public) usercontrol.button.Click += new EventHandler(usercontrolButton_Click);
register the button's Click event within your usercontrol