How to know what control the mouse has clicked in a canvas? - c#

I am creating a C# WPF application and looking for a way to do the following:
I have a canvas with different user controls in it and a button.
When I click on the button the cursor change to a hand (Canvas.Cursor = Cursors.Hand)
Then if I click on one of the controls I get a message box showing the name of the control clicked (the name is a public property of the control).
If I click somewhere else i the cursor resets and I should click on the button again before I can get the name again.
I tried playing with events and handlers but couldn't achieve what I wanted.
Thank you very much for you help

You can use Canvas.MouseDown and use VisualTreeHelper.HitTest() with GetPosition() of the mouse down event args to get the element that was clicked.
<Canvas Name="myCanvas" MouseDown="MouseDownHandler" />
public void MouseDownHandler(object sender, MouseButtonEventArgs e)
{
HitTestResult target = VisualTreeHelper.HitTest(myCanvas, e.GetPosition(myCanvas));
while(!(target is Control) && (target != null))
{
target = VisualTreeHelper.GetParent(target);
}
// now if target is not null, it's the control that was clicked...
}
Then you can use VisualTreeHelper.GetParent() (in a while loop) to get the control that was clicked.

Related

Changing visiblity screwing up events in C#?

I have setup a Panel that has a number of Buttons on it. These Buttons Visible Property is set to false. When I move the mouse over the Panel they became Visible and when I move the mouse out of the Panel they once again became invisible. This all works fine.
The code to do this is:
private void _Display_MouseEnter(object sender, EventArgs e)
{
foreach (Control C in _Display.Controls)
{
C.Visible = true;
}
}
private void _Display_MouseLeave(object sender, EventArgs e)
{
foreach (Control C in _Display.Controls)
{
C.Visible = false;
}
}
The problem is the Events I have set for the Buttons seem to get removed by doing this. If I don't change the Buttons visiblity the events fire as normal. I have set the events in the Designer.
Am I missing something or is this how its supposed to work and I have to resubscribe my events each time I change the Buttons visiblity?
Thanks
Danny
I did some research on that and apparently when the cursor enters one of the buttons the Panel's MouseEnter and MouseLeave events fire until the cursor leaves that button so what it does is not allowing your buttons to catch the Click event.
I think the best solution would be to get the cursor position and check if it is within your panel and then set your buttons visibility.

Focus in parent even if click on child element

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.

How to know which Image the MouseClick event occured?

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;
}

C# click on control

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.

Tooltip not displaying, flashes when control is clicked

I have a check box that is disabled that should be showing a tooltip when hovered over, but instead nothing happens. Once the checkbox is clicked on the tooltip shows momentarily then flashes on and off very fast. What could be causing this?
The tooltip should also be showing for every control involved, but shows for some and not others eventhough the tooltip is explicitly set for all controls. What could be causing this behavior?
Here is the event handler:
this.MouseHover += new EventHandler(OrderSummaryDetails_MouseHover);
void EventHandler_MouseHover(object sender, EventArgs e)
{
if (someCondition)
{
this.mFormTips.Show("Please open order form to manually modify this order", this);
}
}
I can't be positive, but if using WinForms, and you have your checkbox disabled (as in not enabled), then the checkbox will not receive events. This will cause tooltips not to show up properly.
I had the exact same problem before with a image button and what I ended up having to do was to create a gray scale of the image and swap it out when I wanted the button to be "disabled". I had to add the tooltip to the button and the image (two separate UI elements) and swap out the UI elements.
I added a MouseMove event and applied it to all the controls.
void OrderSummaryDetails_MouseMove(object sender, MouseEventArgs e)
{
Control control = GetChildAtPoint(e.Location);
if (control != null)
{
string toolTipString = mFormTips.GetToolTip(control);
this.mFormTips.ShowAlways = true;
// trigger the tooltip with no delay and some basic positioning just to give you an idea
mFormTips.Show(toolTipString, control, control.Width / 2, control.Height / 2);
}
}

Categories

Resources