Custom event for wpf UIElement - wpf

Is is possible to fire event when a UIElement's location is changed in wpf? We can fire location changed event in case of Windows but can we have a custom event which fires when a UIElement's location is changed in the Window.

It's not possible for the general case. The UIElement doesn't even know the location it's rendered to.
You can do it for particular cases, though. You can use events of the layout parent, like the Left and Top attached property of the Canvas, the scroll offset of a ScrollViewer, etc., depending on where your UIElement is in the visual tree.

Maybe this link will help you, UIElement supports a lot of Events. I think what you are looking for are Manipulation Events or the LayoutUpdate Event.
MSDN UIElement Class

Related

How to disable mousedown event on Silverlight listbox

I have a third-party image control inside an SL5 listbox itemtemplate. This makes for a nice scrollable gallery of images.
Now for the trouble: the third-party image control (LeadTools v17.5) has an interactive feature wherein mouseleftbuttondown causes a draggable magnifying glass to appear. This works great when the control is not hosted in a listbox. But clicking on the control within a listboxitem does nothing. After some research I "believe" this is because the listboxitem is trapping the mouseleftbuttondown event marking it as handled so the image control never sees it. In my application I have no need to handle the mouseleftbuttondown event at the listbox level (other buttons etc control my UI). Assuming I'm correct, is there a way to stop the listboxitem from listenting to this event?
Or perhaps I'm completely wrong about the cause. In that case any other ideas about why the listbox appears to block mouseleftbuttondown events from reaching the controls within is appreciated.
Thanks,
Mark
Instead of trying to keep the ListBoxItem from handling the event, you might be able to use UIElement.AddHandler with handledEventsToo: true, if you can get the necessary UIElement and Delegate references to trigger the image control's feature.
Thanks for your suggestions. In this case it turns out the quick solution was to add this handler to the image control:
private void leadGalleryImageViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
e.Handled = true;
}
From this I gather the mouseleftbuttondown event was being received by the image control all along, but likely as it bubbled up through the listitem and beyond, the listitem did its thing then marked it as handled effectively killing anything the image control was trying to do. By marking the event as handled at the image control level, the listitem ignores it.

MouseLeftButtonUpEvent & Bubbling in Canvas

I think I'm going crazy...
I have Canvas with event handlers for MouseMove & MouseLeftButtonUp.
However MouseLeftButtonUp is not being fired when it happens with cursor over TextBlock that is inside canvas.
(it fires just fine when I release mouse button in empty space of the canvas)
I tried attaching handler via AddHandler and using regular += syntax, nothing seems to work.
I tried using Canvas.CaptureMouse() but it doesnt seem to work either (CaptureMouse returns true btw).
MouseLeftButtonUp just doesnt want to propagate to it's parent when it happens over TextBlock (or any other element with IsHitTestVisible = true) inside Canvas.
Please help.
First I'd like to say that you are not going crazy. I've seen this before in Silverlight applications. Silverlight has some interesting event strategies. Silverlight events follow a bubble up approach for routed events but not with all events (msdn has some information on this) The events you are listening to are in that list but they are being handled by the TextBlock. Most UIElements have IsHitTestVisible=true so that mouse events and others are captured by the control and not bubbled up to its parent. Setting IsHitTestVisible=false should solve the problem. Other than that I can tell you what I have tried to overcome this issue when needing IsHitTestVisible=true.
Set the event hanlder from the parent on the TextBlock. Downside is you need to do this for every control in your canvas.
Try to fire the event through an extension class. I could not get this one to work cause i couldn't fire events using reflection.
You mentioned you tried AddHandler - did you try the AddHandler overload that accepts two parameters, the second one being "true" to indicate you want to get handled events as well?

DrawingVisual selection working - deselecting, not so much

ok, I got the several shapes in my custom FrameworkElement to allow for hit testing selection. Next comes the task of deselecting all shapes if the user clicks on a blank area. This doesn't work by default because the FrameworkElement doesn't fire a mousedown event if you click on a "blank" area.
Do people solve this by putting a background rectangle as the first drawingvisual in their frameworkelements (that will accept clicks, but will be treated differently than clicking on the foreground objects), or do they handle the "empty" mousedown events in the class that constructs the FrameworkElement (which in my case is a Viewmodel in an MVVM setup)? Or a third way I'm not considering?
thank you
Try setting the background to transparant and you most likely will get mouse down events.
Instead of deriving from FrameworkElement, derive your control from Control class. The Control class has the Background property which you will set to transparant to get mouse down events. See below link for comments about deriving directly from FrameworkElement:
http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.aspx

Control a Winforms tooltip's location

Is there any way to control a tooltip's location on a Winform? I can handle the Popup event, but in the event handler I can only change the size, not the location. I could use the OnMouseEnter/Leave events of the control to manually show a tooltip, but then I lose the benefits of the AutomaticDelay property of a normal tooltip.
The ToolTip.Show method has some overloads that allow this. Check it out.

WPF Events and references to objects, and how to manage them

I have a small WPF application, which has a Canvas and a Grid. I placed some custom user controls on the Grid. Now I would like to capture some mouse events on them. As a consequence of one event I would like to add (or modify) something to the canvas. However in the user control, you don't have a reference to the underlying canvas. First question, is there a way to get this reference, for example like getElementById(..) in JavaScript.
Also I know that you should avoid such references, if you want a clean architecture. In this case, whats a good practice to catch events at a specific user control and then to be able to invoke something on another object.
You do have access to the Canvas, Grid or any other element in your UserControl. The easiest way yo access them is to make sure each one has a name which is done by using the x:Name attribute.
<Grid x:Name="myGrid">
Then within your UserControl you can access it with myGrid. To access a Grid from outside the UserControl you would need to create a method in your UserControl that allowed you to manipulate it.
There is a this.FindName method you can use in a UserControl which is the equivalent of javascript's getElementById but you shouldn't need to use it given you can access objects directly with their name.
WPF has a new event architecture that may help you out here. So called "routed" events may either "tunnel" from the logical root container, through all intermediate containers, to the event source element, or "bubble" from the source element up (i.e. "tunneling" and "bubbling" events propagate in opposite directions).
All that to say that you can typically intercept events from child elements by registering an event handler at the container. Here's an example of intercepting button click events from buttons in a StackPanel:
<StackPanel ButtonBase.Click="HandleButtonClick">
<Button>Foo</Button>
<Button>Bar</Button>
</StackPanel>
And HandleButtonClick might be implemented like this:
private void HandleButtonClick(object sender, RoutedEventArgs e)
{
var button = e.OriginalSource as Button;
if (button != null) MessageBox.Show(button.Content.ToString());
}
Depending on what sort of "custom controls" you are using, this may not be possible. This is because not all events are "routed" events. WPF control events are usually routed events.

Resources