I have a UserControl (let's call it "PresentationCell") which contains a label, and an PictureBox.
In another control, which is using this PresentationCell, I have added an event
presentationCell.GotFocus += OnFocus;
private void OnFocus(object sender, EventArgs e)
{
if (sender is PresentationCell current)
current.BackColor = Color.Azure;
}
This will not be fired, if I click / focus on the Label or PictureBox that is within the PresentationCell.
How can I make it fire, when just something within the PresentationCell is in focus?
The problem here is, that the Label and PictureBox controls aren't selectable controls, so they aren't able to receive focus from mouse clicks.
What you could to instead, is to handle the mouse click event and check if you have hit the PresentationCell. If the PresentationCell is hit you can programatically set the focus like so:
hitPresentationCell.Focus();
This will then fire the GotFocus event.
In your OnFocus method you will have to switch the focus to another control or the event will fire endlessly.
Related
I have 2 images for 2 players on my windows form. I have added a MouseClick event for both of them. Now when I mouse click, it activates both the events for both the players. I wanted to know only one player where I am clicking.
How do I do that?
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this._player1_MouseClick);
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this._player2_MouseClick);
Assume you have two PictureBox controls with images. Thus you have posted code from designer, I also assume that you are subscribing to events via designer.
Select one of PictureBox controls
In Events tab find Click property, type-in Player_Click as handler name and hit Enter. You have subscribed to Click event of first control.
Select second PictureBox
In Events tab find Click property, click on drop-down and select Player_Click as well. Hit Enter. You have used same event handler to subscribe to Click event of second control.
Now go to code view (you can double click any of those controls for that) and find Player_Click method
In order to find which control was clicked you need to cast sender argument to PictureBox type:
private void Player_Click(object sender, EventArgs e)
{
var pictureBox = (PictureBox)sender;
// use control which was clicked. e.g. get it's name
var name = pictureBox.Name;
}
I'm trying to create a custom control which fires an even on click.
My control is just a panel with a couple of labels and a picturebox inside.
The click works perfectly, the only issue is that I have to click the background of the control and if I press on the picturebox, is not working.
I've added the on click event to the control, but I would like to press in every place of it to trigger the event, not just the background of the panel.
I thought about adding a transparent object that covers entirely the control. I actually don't like this idea, however, I've tried with a picturebox, but i cannot see through it. It's not transparent. I can just see the panel background but It covers the labels and the image.
Thanks for the support.
If you just have a couple of objects in your panel, you can hook the Click event of all objects it contains to the same event handler, there is nothing wrong doing this.
public class MyUserControl : UserControl
{
public event Action<MyUserControl> MyControlClick
public string ID {get; set;}
public MyUserControl()
{
InitializeComponents();
// The same event handler code will be used for the three controls
myPictureBox.Click += global_Click;
myLabel1.Click += global_Click;
myLabel2.Click += global_Click;
this.Click += global_Click;
}
void global_Click(object sender, EventArgs e)
{
if (MyControlClick != null)
MyControlClick(this);
}
}
If you have a more important amount of objects, you can rely on this answer to create a truly transparent panel that handles clicks. The drawback is that you will have to detect which object has been clicked by using HitTest based on the mouse location.
On the form side :
aControl.MyControlClick += aControl_MyControlClick;
// ...
// This code is triggered when a MyUserControl is clicked
void aControl_MyControlClick(MyUserControl ctl)
{
MessageBox.Show(ctl.ID);
}
Actually! You cannot raise any event to the element in the Usercontrol unless you have to apply own method to your usercontrol or you can disable the element in the usercontrol but it will change the color of that element but It will raise the click event when you click your control.
I have a UserControl defined such that:
UserControl
TextBox
Button (Clear)
I have a GotFocus handler on the UserControl so that whenever it gets focus, it calls TextBox.Focus(). The problem I am running into is that If I click the clear button, it clears the text and then refocuses to the textbox, triggering two GotFocus events on my control. I want this to act as either:
One GotFocus event
One GotFocus event (button), One LostFocus event(button), One GotFocus event (textbox)
I have played with FocusManager.IsFocusScope to no avail. Is there even a way to trigger a manual LostFocus right before I call Textbox.Focus?
In your GotFocus event you can check whether the mouse is over the clear button and whether the left mouse button is pressed, in such a case you can ignore the call to TextBox.Focus():
private void UserControl_GotFocus(object sender, RoutedEventArgs e)
{
if ((this.clearButton.IsMouseOver && Mouse.LeftButton == MouseButtonState.Pressed) == false)
{
this.textBox.Focus();
}
}
I have Windows Form named - Form1 and inside Form1 I have a panel named panel1. I use this panel only to add buttons in him. For now there are exactly 9 buttons but I intend to change their number dynamicly if this has something to do with my current problem. What I need is way to detect a when a button from this panel is clicked (I have other buttons too but, they are in Form1 outside the panel) and also to know exactly which button was clicked.
I tried this:
private void panel1_Click(object sender, EventArgs e)
{
MessageBox.Show("HI" + sender);
}
As you can see, it's not much, but was enough to see that I can't do that using pnael1's_click event. Using this code I get the message box when I click anywhere in the panel except the buttons. So how can I do that. Is it possible to do it from inside panel1 or I should group those buttons using another approach but it's important to be able to keep the difference between those buttons which are now in panel1 and the other buttons I may (and in in fact I do have)?
When creating the dynamic buttons, you register that button instance's Click event and attach to an event handler (a single handler can handle all buttons' click event):
var dynamicButton1 = new Button();
dynamicButton1.Click += MyButtonClickHandler;
As long as MyButtonClickHandler has a signature that's suitable for a Click event (that's any method returning void and taking an object and an EventArgs, the handler should respond to a dynamic button's click event for as long as the button instance exists.
As long as you aren't adding controls dynamically over time, and the number of buttons is fixed as soon as the form is initialized, you can use this to add a click event handler to all buttons within a panel:
foreach (var button in panel.Controls.OfType<Button>())
{
button.Click += HandleClick;
}
I added a Panel inside a UserControl i design time.
Then, I added this control to a form.
I want to show a focus dashed border when the control has the focus.
Unfortunately, the Enter event from the panel never fires. I only get a fire when I click on the user control itself.
To extend this question. How can I forward events from controls inside a user control to the base user control? A comment from Hans Passant in this question says that by default events are forwarded to their direct parent. I didn't change any of the control's properties. What am I doing wrong? Is there an obvious property I need to change on each control i order to force it to forward unhandled events?
I am using DevExpress controls but this behavior is same in windows WinForms controls.
edit: I understand that panel might not be able to get focus. If this is true, how do I forward each mouse event to the parent control?
Based on your comment, from inside your UserControl, handle the panel's MouseDown event and set the focus to the parent control:
public UserControl1() {
InitializeComponent();
panel1.MouseDown += new MouseEventHandler(panel1_MouseDown);
}
void panel1_MouseDown(object sender, MouseEventArgs e) {
if (!this.Focused)
this.Focus();
}
Use panel1.Select() on MouseClick event of the panel and you will be able to trigger panel1.Enter and panel1.Leave