views:

308

answers:

1

Obviously, the straightforward answer to the question is "No", but what's the best way for me to achieve that kind of effect? To explain, here's a bit of background...

I have an app that displays an Image plus a couple of layers of overlaid shapes on that image. All of these are placed within a Grid cell, overlapping each other, with the image at the bottom of the local z-order. For speed, the overlays are implemented as classes derived from FrameworkElement and they create and manage their own visuals.

Here's a basic diagram (albeit exploded into 3D) of how the layers are arranged and what interaction they have/need:


overlapped_controls.png


As you can see, the upper overlay must allow the user to drag out a new rectangle anywhere in the image. To that end, I've given it a transparent background, acting like a plate of glass on which you can draw. The obvious drawback of this is that it stops all mouse events passing through down to the lower layers.

I'd really like to only trap the left mouse button's events in that top layer's transparent area and let other events hit layers further down the z-order.

Is there a WPF-minded pattern I should be following for this kind of thing? Any kind of best practice or technique?

I'm still fairly fresh to WPF, but want to write a solution that's in tune with the API. Thanks.

+1  A: 

I would use the PreviewMouseDown event on the elements that need to be right-clicked, and use LeftMouseDown on the elements that need to be left-clicked. The PreviewMouseDown event will still fire, but you can write handlers to ignore left clicks for it.

This is actually a pattern I'm using to display shapes on top of images, so that a user can circle a part of the image to highlight it. I have the PreviewMouseDown on the image, and it functions normally all the time, then I have a LeftMouseDown handler on any shapes so that they can be moved, deleted, etc.

md5sum
Thanks - I've uploaded the image to a new site and updated its URL accordingly. Hope it's fixed it. And thanks for the tip on PreviewMouseDown. I had considered it, but wasn't sure it was the by-the-book way to go about it.
Mal Ross
Well, to be quite honest, sometimes the "by-the-book" way just doesn't work for all situations. In my situation, I'm not putting my shapes in layers of their own. I'm not really sure what the official way to do it is, but the `PreviewMouseDown` way looks really clean in my code the way I have to have everything set up for my other events.
md5sum
I was wondering how you had your stuff structured. I tried the PreviewXXX approach before realising it would never work for me because my image isn't a parent of the shapes layers in the logical (or visual) tree. I really want to keep the shapes layers' logic separate from the image, mind, so I suspect I'll end up putting both things inside some kind of parent control and using the PreviewXXX events to offer functionality to the child layers. We'll see. :) I'll post again here if I come up with something nice.
Mal Ross
Yes, you would have to have them all with a single logical parent. I have <Grid><Image></Image><Grid><Shape(s)></Shape(s)></Grid></Grid> with my `PreviewMouseDown` event handled on the parent grid.
md5sum