In a Silverlight 2 app, I am using Rectangles on a Canvas to draw a representation of data. I would like to have mouse clicks on the Rectangles be passed on to the control that owns the Canvas. I would also like to be able to show a tooltip with a summary of the data when the mouse is over a Rectangle.
So far I've only been able to achieve one item or the other. If I make the Rectangles have their IsHitTestVisible property = false, the tooltips don't work, but the owning control will receive the mouse clicks. If I set it to true, then tooltips do work, but the clicks don't get passed on.
Is there a way to have a Silverlight item be IsHitTestvisible = true, and pass on the mouse clicks?
I'm not sure why the tooltip and mouse left down / up is being linked, In SL3 the mouse left down / up will bubble unless it gets marked as handled by a routine / object. It sounds more like the event is not bubbling thru the parent controls. AFAIK SL2 does the same. (could be wrong on that one)
What is the visual tree from the outer parent to the inner rectangle?
Have Canvas pass a reference of itself to Rectangles when they're constructed. When a rectangle is clicked, call a method on Canvas.
Edit:
If Rectangles and Canvas are library classes, subclass them to add functionality you need.
Related
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.
I am trying to achieve functionality similar to that of a Popup, without using a Popup, but instead adorning my ContentControl with a basic adorner. Basically, I want the ContentControl to have an "overlay" effect, whereby it is the topmost object, above all other elements - similiar to that of the Popup control.
Here is the problem that I am running into, and I am hoping that someone can point out where I am going wrong:
I have a stand grid with two row definitions. The first row contains a UI element - for example, a rectangle. The second row contains a custom control that I have developed to emulate the functionality of a "drawer" sliding out. Basically, when I click on button, I am going to animate a TranslateTransform to "slide" my ContentControl "up". This works fine - except that it gets cropped underneath the rectange in the first row of the grid. If I remove the row definitions in the grid, then when the desired behavior is achieved - the ContentControl is moved "up" and partially "on top" of the rectangle. The rectangle is merely a place holder for what I am trying to achieve. I basically want to have a drawer type control that can slide out and be on top of all other controls.
I am somewhat new to using the Adorner class, so, I am hoping that someone can please point out where I am going wrong.
Thanks.
Chris
Change the parent of the adorner to the full grid, and not just your control. If you put a control in a grid row, and set the adorner to adorn the control, it will usually be clipped to that row because the control is.
My target is an entire listbox clipped in a canvas, but I guess there should be something that can work for all controls?
How to make a control draggable and even attached x or y constraints?
You would have to cycle thru all the child controls and add handlers to mouse events.
Within those events you control the drag and the bounds.
I've got a Silverlight 4 custom control that basically is several Canvas elements wrapped inside a ScrollViewer. The user can set a property to determine whether to scroll or zoom when using their mouses wheel. In the custom control's MouseWheel event, I check to see if they want to scroll or zoom. If zooming, I determine the delta and modify the custom control's zoom level (which then handles the zooming code for me).
The problem is that zooming won't start until the ScrollViewer's current position of the vertical scrollbar is at the top or bottom of the scrollbar. Once their, then the zooming works perfectly.
Does anyone have any suggestions on how I can prevent scrolling completely so that I only zoom (when the user wants to zoom, that is)?
Thanks!
Looks like one of my child elements was hogging the MouseWheel event. I traced this by adding Debug.WriteLine statements to each of the child element's MouseWheel event as well as the parent control's MouseWheel event.
So, I can't blame SL4. Just myself. :)
I'm writing an XBAP with a complex Popup (Canvas Z-index of 99 with a grid on it...) that I would like to "attach" to the button that opens it and follow that button around wherever it goes on the screen. For example, if the button is in a ListBox or an XamDataGrid I would like the popup to follow the button as it scrolls through. If it is beneath an Expander I want it to stay attached to the button when the expander forces it to move, etc.
Any Ideas?
When using a Popup, neither PlacementTarget nor CustomPopupPlacementCallback is used after the popup has originally appeared. So any use of these properties will not allow the popup to track the button as it moves.
Several ways occur to me of achieving what you desire:
Attach a custom Adorner to the button and put the popup inside it. Disadvantage: Popup is not connected to Button or surrounding elements, so it won't inherit properties & DataContext from them.
Attach a custom Adorner to the button. This adorner will get measure and arrange calls when the button moves relative to the AdornerLayer, allowing you to manually update the Popup position. As long as your AdornerDecorator doesn't move relative to your Window (eg if it is the direct child of the Window), you can easily detect the AdornerLayer being moved by monitoring changes to Window size. Disadvantage: Complex to code & get right.
Don't use a Popup at all. Instead wrap the button in a <Grid> alongside a <Canvas> with zero width and height and the desired position. Inside the <Canvas> add the UserControl for the popup with an appropriate ZIndex. It will extend past the edge f the Canvas, which is just fine in WPF. Instead of using a Popup control just control the visibility of the UserControl. Disadvantage: Will not really be totally on top of all other objects, can't extend off edge of window (may not be an issue for XBAP, though).
I'm not sure if it will auto-update for you or not, but the PlacementTarget property allows you to specify a control to position the popup relative to. If that doesn't work, then maybe CustomPopupPlacementCallback will do the trick?