DrawingVisual selection working - deselecting, not so much - wpf

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

Related

Click event on canvas with background

I have UserControl, which contains Canvas (in Grid).
When I just clicked on canvas event PreviewMouseLeftButtonDown or MouseLeftButtonDown works perfectly, but when I set canvas.Background = new ImageBrush(imgs); and try to click on canvas, events doesn't raising. I tried to make same events for grid (canvas parent), but result was the same.
UPD1: canvas has children - rectangle (from System.Windows.Shapes) around cursor, maybe it somehow affect on events.
In wpf there are two possible scenarios where hit testing (clicking with mouse somewhere) is not working. These two are ment to be that way and it is by design. I am talking about when your Background is NULL or when you have the property IsHitTestVisible set to false.
In any other case hit testing/clicking will work.
I assume your background is null somehow. Maybe imgs throws error which will be catched in an empty try/catch block internally at render time.
Tell us is the background property of your canvas null?
There is a nice tool called Snoop which allows you to snoop an wpf app and change properties at runtime. Use that tool to change the background and tell us about the results.
EDIT:
First of all the default value of Canvas Background is null therefore by default you can click as often you wish on Canvas and nothing will happen.
As soon you change the Background to Yellow it clicking will work and your handler will be called.

How to set focus to UserControl (make it selectable)?

I need to set focus to UserControl itself, not its child.
Otherwise I cannot implement insertion from the buffer. :(
Setting Focusable=True doesn't help.
Google and SO tells only how to set focus to UserControl child.
My control contains:
- Toolbar with several buttons bound to commands of the corresponding
VM
- TextBox which is the input for the filter
- DataGrid - list of items.
I need to bind Ctrl+V command to VM. But to handle this gesture UserControl must have focus within. When there are no items in the grid (VM's collection is empty) buttons are disabled and the only element which can get focus is TextBox. But it handles Ctrl+V in its own way and I don't want to change this behavior.
Thus, I need something to set focus to when I click the area of UserControl.
I believe UserControl is the best candidate for it.
But I don't know how to make it selectable.
The whole problem was in my misunderstanding of controls' behavior.
This SO question clearly shows it I believe.
Thus, setting UserControl.Focusable = true is not sufficient. To make it navigatable via keyboard IsTabStop must be true also. And to make UC selectable by mouse click we should call Focus() in mouse eventhandler. That's it.

How to change panel width when panel's width is already binded to a Storyboard

I have applied a storyboard animation at design time to change a stackpanel width. But when I explicitly change same control's width on a button click, then there is no change in its width.
When I do not apply any storyBoard at design time, then width change works.
Is there any way to remove storyboard binding from a panel control and apply same whenever I want on a button click.
thanks
DependencyPropertys react to change requests from different sources with different precedences. You can find out more in the Dependency Property Value Precedence article on MSDN. In your situation, the change requests to the StackPanel.Width DependencyProperty sent from the Animation object override any changes made in a Trigger Setter object.
The easiest thing to do is to pause or stop the Storyboard in the Button.Click handler before you change the StackPanel.Width. See this post which deals with a similar situation. You can find further information in the MSDN Storyboard.Pause Method article.

wpf selecting controls inside a listbox

I have a textbox and some labels inside the data template of bounded listbox.
When I click on any label the whole item is highlighted in blue, but when I click directly on a different textbox the selection does not change.
Is there a way to make the selection of the listbox change even when a textbox is clicked?
thanks
This is what I've exactly asked few days ago, see post: "WPF: Trigger SelectedIndex changed whilst clicking on any control within a ListBoxItem area"
basically there are few solutions, using code behind and XAML, but I've not verified latter approach yet
The reason is because the TextBox handles the click event in order to receive focus. There are a number of ways to handle this, including but not limited to:
stop the TextBox handling mouse events (which prevents the user from focussing it using the mouse)
use an eventhandler when the TextBox gains focus (or PreviewClick or similar), to select the parent ListItem

WPF custom panel control doesn't respond to mouse events

I've created a custom panel control and would like to have it respond to a mouse move event, however, when I add an event handler like so:
Private Sub FloatingPanel_MouseMove(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles Me.MouseMove
End Sub
It only responds when I move the mouse over one of the child controls within the panel. I need to have it respond whenever I move the mouse anywhere inside the custom panel.
Update:
I found the following question which gave me a clue:
WPF - how to best implement a panel with draggable/zoomable children?
I can get mouse events on the
GraphCanvas itself only if it has a
background at the point
This led me to simply set the background which appears to have resolved the issue... My question now is, why? Why should I have to set the background in order to receive a mousemove event?
Update 2: The following code is what ultimately solved the problem (See Kent's answer below).
Protected Overrides Function HitTestCore(ByVal hitTestParameters As System.Windows.Media.PointHitTestParameters) As System.Windows.Media.HitTestResult
Return New PointHitTestResult(Me, hitTestParameters.HitPoint)
End Function
Thank you,
Matt
For the purposes of hit testing, WPF's default hit testing logic has two modes of transparency. One is transparent both visually and to hit testing (#00000000 or by not setting a background at all), the other is transparent only visually and does not preclude hit testing (##00ffffff). You want the latter.
I believe you could also override UIElement.HitTestCore in your custom Panel such that there is no dependency on having the background set.
I actually suspected this might have been the issue here; If the background of a control is null and there is no other subcomponent there your mouse is not moving across the control but accross the control behind it, so it makes sense that you do not get a mouse event from that (it is not very expected though because the bounds of the control may envelope the area).

Resources