I have been looking around for a while for some code that tells what control the mouse has clicked. I have a Form with over 50 controls and I don't want to click each one to make a mouse clicked on. How would I do this?
You can use the Tag property of each control. So set it to something meaningful and on Click event do something like this:
(sender As Control).Tag
EDIT: Also you may do this:
foreach (Control item in this.Controls) //this IS YOUR CURRENT FORM
{
if ((sender as Control).Equals(item))
{
//Do what you want
}
}
Approach One: Individualized Handling
The mouse click event will actually be received by the control on which the mouse is clicked, so the only thing you need to do is handle the MouseClick event for that control. That makes sense if you want mouse clicks to do something different for each of your controls.
This is just the basic event-handling strategy that you should already be familiar with. The event handler method can be wired up either using the designer or manually via code, and looks like this:
private void myControl_MouseClick(object sender, MouseEventArgs e)
{
// do something when the myControl control is clicked
}
Approach Two: Consolidated Handling
If you want the same behavior on multiple controls, you would wire up a single event handler method to handle the MouseClick event for multiple controls. Then, from inside of the event handler method, you would use the sender parameter to identify the control that was clicked. For example, you could cast sender to a Control object and test the value of the Name property.
If you wanted all controls of a certain type to behave a certain way, and all controls of another type to behave a different way, you could have two event handler methods and wire the controls up accordingly by type.
The easiest way to do this is to wire up the event handler methods through code. The designer would work, but it would be overly tedious to use it for each of many controls. For example, in your form's constructor, you could loop over all of the controls and hook up your event handlers:
public MyForm()
{
this.InitializeComponent();
// Wire up your event handlers.
foreach (Control ctrl in this.Controls)
{
if (ctrl is Label)
{
// Wire all Label controls up to do one thing.
ctrl.MouseClick += new MouseEventHandler(LabelControls_MouseClick);
}
else if (ctrl is Button)
{
// Wire up all Button controls to do another thing.
ctrl.MouseClick += new MouseEventHandler(ButtonControls_MouseClick);
}
else
{
// And wire up the rest of the controls to do a third thing.
ctrl.MouseClick += new MouseEventHandler(OtherControls_MouseClick);
}
}
}
private void LabelControls_MouseClick(object sender, MouseEventArgs e)
{
// do something when a Label control is clicked
}
private void ButtonControls_MouseClick(object sender, MouseEventArgs e)
{
// do something when a Button control is clicked
}
private void OtherControls_MouseClick(object sender, MouseEventArgs e)
{
// do something when a control other than a Label or Button is clicked
}
Approach Three: Global Handling
If you've made all of these controls transparent (that is, transparent to mouse events, not visually transparent) so that mouse click events are handled at a higher level (i.e., by your form), you can use the Control.GetChildAtPoint method to determine the control that was clicked on. You just specify the coordinates of the location at which the mouse was clicked, and the method will return the child control (if any) that is located at that point.
private void myForm_MouseClick(object sender, MouseEventArgs e)
{
Control ctrl = Control.GetChildAtPoint(e.Location);
if (ctrl != null)
{
// do something with the clicked control
}
else
{
// if ctrl is null, then the parent form itself was clicked,
// rather than one of its child controls
}
}
I don't really recommend this approach, though, because it violates good object-oriented design. You have to write code to determine which control is which based on its unique properties, instead of just letting the runtime determine and handle that automatically.
Related
Is there a method which initiates on focus change and can be overridden?
My goal is for the program to fetch closest data automatically from database to input fields whenever user changes his focus/presses enter or tab when on corresponding field. I'm still looking for a way to do this when user selects an item by mouse.
I'm aware that this could be implemented on mouse click but I refuse to believe that there is not a general method for focus change.
What about something like this:
foreach(Control ctrl in this.Controls)
{
ctrl.Enter += new EventHandler(Focus_Changed); // Your method to fire
}
Iterate through all controls and add a enter-event. Bind this handler to your method.
Edit:
Just in case you are wondering why "Enter" and not "LostFocus" or something like that: From my knowledge not every control got focus-events. As I've seen so far "Enter" is presented for all. Maybe there are exceptions. Should be checked out...
You could use Control.Enter event and Control.Leave event for that purpose.
See on MSDN Control.Enter and
Control.Leave.
textBox1.Enter += textBox1_Enter;
textBox1.Leave += textBox1_Leave;
private void textBox1_Enter(object sender, System.EventArgs e)
{
// the control got focus
}
private void textBox1_Leave(object sender, System.EventArgs e)
{
// the control lost focus
}
This must have been asked before, but I am fairly new and don't quite know how to express myself...
1) I have a UserControl that basically acts as a toolbar. I re-use the toolbar in each window, hence the need for a uc.
2) The toolbar is filled with buttons
3) the usercontrol doesn't act on the button (no code), but it should pass the event back to the parent window so the code in the parent window fires up.
How can I do this? Is this a routed event? any sample code in vb.net would be appreciated!
On you user control, you need events that you can fire when the buttons are clicked. Then in your form, you handle the events just like you do for every other control. IE:
public event Button1_ClickedEventHandler Button1_Clicked;
public delegate void Button1_ClickedEventHandler(object sender);
private void Button1_Click(object sender, EventArgs e)
{
if (Button1_Clicked != null) {
Button1_Clicked(this);
}
}
You can call the event whatever you want and pass whatever you want. Here you will notice I am NOT sending the button but THIS, which in this case should be the User Control.
I have a UserControlwhich contains some inner controls inside it. something like this:
Now when I use it in my project, I want every point of my control raise the same click event if clicked, just like other controls.
but the problem is: my handler in another project, handles click events just when I click somewhere on the background, not on the button1 or label1.
I can solve it by setting every event in inner controls raise another event for the main control, but it is a bit odd.
How can I make the inner controls don't cover the main control's events?
I'd suggest leveraging the UserControls Load event to iterate over all sub controls in your project and add a handler programmatically for each MouseMoved event. This would be robust enough to handle any new sub controls added. E.g;
private void UserControl1_Load(object sender, EventArgs e)
{
foreach (Control c in Controls)
{
c.MouseMove += Control_Move;
}
}
protected void Control_Move(object sender, MouseEventArgs e)
{
// do stuff here
}
And don't forget to hook your UserControl's MouseMove event to the same Control_Move method
I did something like this in Delphi. The trick was to not add a label, but add a sub class of a label, button, etc, that calls the parents events on the event.
The sub class just overrides Click, Move etc and calls parent. Simple, and saves lots of time if you have a lot of these.
I developping one win-form application which having one custom control with one label and text box, and placed the custom control in one panel with docksytle as fill,
there is mouse click event for panel and custom control both, but when i click only custom control mouse click event is firing not the panel click event,
so anyone please let me know how to call the panel mouse click event.
Are you sure that you really need to invoke click of parent control? In general it would be, in my opinion, a code smell if you will do something like that - especially when it requires some strange constructions.
If you need to react in a same way when clicking on panel and on any child control inside the panel, it should be enough just to call the same method from two event handlers (that is from event handler of parent panel and event handler of child control. If you need, for example, mouse pointer location inside parent panel, you can easily calculate the position of mouse pointer using, for example, PointToScreen() and PointToClient() methods.
This is not a general solution, but maybe it's what you're looking for:
private void CustomControl_MouseClick(object sender, MouseEventArgs e)
{
panel_MouseClick(sender, e);
}
private void panel_MouseClick(object sender, MouseEventArgs e)
{
}
Create Click Event for each control in panel and invoke the parent :
private void This_Click(object sender, EventArgs e)
{
this.InvokeOnClick(this, null);
}
I'm implementing copy-paste in a Windows Forms application.
I need to enable/disable the bar-buttons for this two operations when the user changes the focused element in the application.
I can find the current focused control using something like this: http://www.syncfusion.com/FAQ/windowsforms/faq_c41c.aspx#q1021q, but how can I detect that the focused control has changed?
In your form load event handler you could also loop through all of the controls contained in the form and for each focusable control add an event handler for the Enter event:
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control control in Controls)
{
control.Enter += ControlReceivedFocus;
}
}
void ControlReceivedFocus(object sender, EventArgs e)
{
Debug.WriteLine(sender + " received focus.");
}
My proposal is to use Application.Idle event.
Write logic that enables/disables your buttons in Application.Idle event.
Subscribe to Application.Idle event on form shown event
Check button availability on button click (so you never pass accidental click under heavy load)
Do not forget to remove Idle handler on form disposing (or closing), because this is static event
Using this technique you will always have correct buttons state, and you not need to worry about subscribing to many controls events to detect focus change. This is also light-weight approach, because Idle event is raised only when application is not busy.
I think you should add an event handler to the control (or if you have many of the same type, subclass it, and override the appropriate OnChange handler). This way you won't have to 'find' the focused control (it will be given as the sender parameter), and the event will only arise when the change actually happened.
To detect the focus on a control you can create this event:
void MyGotFocus(object sender, EventArgs e)
{
if (sender is TextBox)
{
//TODO YOUR OPERATION
//FOR EXAMPLE
(sender as TextBox).SelectAll();
}
}
and the next step is to associate the control and event by code:
myText1.GotFocus += MyGotFocus;
myText2.GotFocus += MyGotFocus;