wpf catching mouse down outside my custom control - wpf

I'm building a custom control in WPF. I want to catch a mouse down event when my control is in focus but the user clicks outside the control. Is there a way to do that and if so how?
My control inherits from ListBox.

You can use UIElement.CaptureMouse and it's partner UIElement.ReleaseMouseCapture to capture all mouse events to a single control, regardless of what the mouse was over when the event occurred.
In your example I would capture the mouse when the control has focus, and release the mouse when the control looses focus.

Suppose you have a Window with a TextBox on it.
By registering to Window's MouseDown event,
MouseDown += new MouseButtonEventHandler(Window_MouseDown);
You can use following code
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (TextBox1.IsFocused)
{
MessageBox.Show("TextBox1 in focus.");
}
}
To catch this event if TextBox1 is in focus.

Related

C# WPF - Canvas MouseMove event firing even when mouse moves over child control

How to make it so the Canvas MouseMove event only fires if my mouse is over the Canvas and the Canvas only?
I have a TextBox as a child of the Canvas and it still fires when my mouse is moving over that TextBox, i would like this to not happen, it should only fire when the mouse is moving over the Canvas background/blank space for example.
How to make it so the canvas MouseMove event only fires if my mouse is over the Canvas and the Canvas only?
You can't prevent the event from being fired but you can check whether the mouse is directly over the Canvas area in your event handler and simply do nothing if it isn't:
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.DirectlyOver == sender)
{
//your code...
}
//else, i.e. when the mouse moves over the TextBox or another child element, do nothing
}
You have to listen to the preview version of that event on the canvas PreviewMouseMove and set the e.Handled = true.
Take a look at this url
https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/routed-events-overview

LostFocus event of a window isn't firing

I have a window:
<Window ...
LostFocus="SpecialLettersLayout_OnLostFocus">
....
</Window>
In this window I have a canvas, and in it I have a Path object which has a non-rectangular form.
In this window I call the LostFocus event. In the .xaml.cs file for that window, I define the SpecialLettersLayout_OnLostFocus event:
private void SpecialLettersLayout_OnLostFocus(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
In my application I have a window and when I click on a button, this window is opened. This window is smaller than the background window, so that means that the background window is still visible.
When I click on the background window I want to hide the small window, because its focus is lost. However, the SpecialLettersLayout_OnLostFocus event isn't hit. Why is that happening?
The LostFocus event is used for logical focus. What you need here is a physical focus which has another name called LostKeyboardFocus.
Logical focus involves using of FocusManager. I'm not really sure when LostFocus is triggered but it's not the traditional LostFocus you thought. Instead we have to use LostKeyboardFocus. Also you may have to change your handler to suit the LostKeyboardFocus event. The handler type is KeyboardFocusChangedEventHandler.
In the end what helped me was the Deactivated event, which didn't work in combination with ShowDialog(), so I used it with Show() instead.

XAML Window MouseDown event beats Image event

I'm using WPF to design a borderless, movable application window.
In order to manually perform the ability to drag and drop the window, I've added an OnMouseDown event to the <Window> element, that executes a corresponding C# function (this.DragMove()).
Additionally, I need an <Image> button to allow some operation (with the OnMouseUp event this time). Note that it has to be an Image tag, and not a Button.
Unfortunately, the Image event fired only when the right mouse button is clicked, probably because the left button is held to the window event. Am I right?
When someone clicks the Image button, I want only the Image event to be triggered. How can I do it?
Problem you're facing is most probably related to event routing. The idea is that if your handler doesn't mark event as a Handled it will be routed to the next listener unless reach end of chain or one of listeners/handlers will set it as Hadnled.
So if you have MouseDown event handler for both Window and Image you should keep in mind that routing will stop at a point when you will set e.Handled = true;:
private void Window_OnMouseDown(object sender, KeyEventArgs e)
{
e.Handled = false; // will NOT break event chain;
}
You can always check a type of sender so it will make possible for you to differ Image and Window events:
private void Image_OnMouseDown(object sender, KeyEventArgs e)
{
if (sender is Image)
{
// Handle Image.MouseDown
e.Handled = true; // we don't need to push event further;
}
}
Its because of WPF bubbling and tunnelling events. so what u can do is whenever u handle event on button use bubbling for that means you can use previewevents for that for both button and window and whenever you just want to handle event for button then after last line of code in button click just write down like this.
e.handled=true;
// here e is the event argument which u will get in your preview event.so now window dragging event will not work.
i would just suggest first clear the idea of bubbling(preview mouse event) and tunneling in wpf.
Difference between Bubbling and Tunneling events
and go through some of the example of bubbling and tunnelling. you will get better idea.
http://www.codeproject.com/Articles/464926/To-bubble-or-tunnel-basic-WPF-events

How to determine what caused GotFocus event of WPF TextBox - mouse click or TAB key?

How to determine what caused GotFocus event of WPF TextBox - mouse click or TAB key?
I need to change border color if focus was set with TAB key and leave border's standart color if focus was set with mouse click. So I need to extract from event args what caused an event, or (better) write trigger to put it into TextBox style.
I would suggest using the OnKeyUp and OnMouseUp events rather than the GotFocus event to determine this. In OnKeyUp, you will need to test (see Eventargs) that it was the Tab key that was pressed.
Could you extend the WPF TextBox and then use that for all your text boxes instead? Then you could have some overridden events to determine how you were focused, or to do the border changes.
class MySpecialTextBox : TextBox
{
protected override void OnIsKeyboardFocusWithinChanged(System.Windows.DependencyPropertyChangedEventArgs e)
{
// Focused by keyboard
}
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
// Focused by mouse
}
protected override void OnIsMouseCaptureWithinChanged(System.Windows.DependencyPropertyChangedEventArgs e)
{
// Focused by mouse
}
}

How can I raise a parent event from a user control in WPF?

I have a user control that is loaded into the parent window, and I want to raise a parent event when a button on the user control is clicked. How can I communicate with the parent through my user control in WPF?
First way that comes to mind is to have your UserControl raise an event that the parent window is listening to. The parent can then raise the event you want.
You're looking for Routed Events.
The Click event on Button is a RoutedEvent, so if your UserControl has a button then you can handle that event in the window. Add an attribute ButtonBase.Click="Window_Click" to the Window in your XAML and a handler private void Window_Click(object sender, RoutedEventArgs e) in the code-behind, and it will get called when any button in the window is clicked.

Resources