(1 item) |
|
(1 item) |
|
(5 items) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(6 items) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(4 items) |
|
(2 items) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(2 items) |
|
(5 items) |
|
(3 items) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(3 items) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(8 items) |
|
(2 items) |
|
(7 items) |
|
(2 items) |
|
(2 items) |
|
(1 item) |
|
(2 items) |
|
(1 item) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(5 items) |
|
(1 item) |
|
(3 items) |
|
(2 items) |
|
(2 items) |
|
(8 items) |
|
(7 items) |
|
(3 items) |
|
(7 items) |
|
(6 items) |
|
(1 item) |
|
(2 items) |
|
(5 items) |
|
(5 items) |
|
(7 items) |
|
(3 items) |
|
(7 items) |
|
(16 items) |
|
(10 items) |
|
(27 items) |
|
(15 items) |
|
(15 items) |
|
(13 items) |
|
(16 items) |
|
(15 items) |
The current version of Avalon (Beta 1 RC1, aka May 2005 CTP) supports the VisuaBrush
. This is a nifty little brush
that you can tell to look like any Visual
. What's a Visual
? Any visible element in an Avalon application -
they all derive from Visual
.
Something I've been meaning to get around to is using this as a simple way of letting the user zoom in on stuff in the UI.
The nice thing about it is that you don't need any special drawing support at all - because a VisualBrush
can
replicate (and transform) any Visual
and all its children, it'll zoom in on pretty much anything.
So here's the kind of effect I wanted:
Here's the relevant bit of markup:
<VisualBrush ViewboxUnits="Absolute" Viewbox="0,0,50,50"
ViewportUnits="RelativeToBoundingBox" Viewport="0,0,1,1"/ >
You can use this as the fill for any shape. There's one thing missing, which is that I've not set the Visual
property -
this doesn't know what it's supposed to be drawing. For some reason I've been unable to find a way of getting it hooked up in markup.
(I tried using a Binding
but for some reason it didn't work.) So I put this in the constructor:
public Window1() { InitializeComponent(); VisualBrush b = (VisualBrush) magnifierEllipse.Fill; b.Visual = mainUI; }
That magnifierEllipse
is one of the elements that make up my magnifying glass. (Obviously there are a few - some for
the surround, and the handle, and one for the main zooming area itself.) There's also some code to handle the moving around of the
mouse. You can download the full code here. Doubtless someone
with drawing talent will take this and make the surrounding graphics look nice, and add a convincing looking reflection graphic on the
magnifier. I'm not too good with drawing, so this is just a technical example...
One of the nice things about this is that it's not just doing a pixel zoom. This is exploiting Avalon's resolution independence. Here's a more extreme zoom, and there's still no pixelation:
While this is quite fun, there are a few issues I had that were a bit unsatisfactory.
First, I wasn't able to use data binding as much as I wanted. I was hoping to bind the textbox that sets the size of the area being
zoomed in on directly to the Viewbox
in the brush. Unfortunately, I wasn't able to make that work, and it seemed to have
something to do with the Rect
type not being very XAML-friendly. It might be possible; I just ended up going for code
because I knew I could make that work. I also wanted to use binding to connect the checkbox to the magnifier's Visibility
property too, but I ended up having to write code there too, because Visibility
is an enumeration. (It supports
Visible
, Hidden
, and Collapsed
states.)
Also, there's a slightly odd problem with the drawing if you move the magnifier too close to the top or the left. The brush ends up getting cropped, and not filling the whole glass. It's possible that I've messed something up somewhere. But it's also possible that it's just a bug in the CTP...
Finally, I wanted the mouse to continue to work when the magnifier was on. Ideally there would be some way of telling Avalon
to ignore the presence of the magnifier graphics for input purposes, and allow clicks to propagate through to the underlying visual.
There may well be a way of doing this, but I couldn't find it. So I ended up using a horrible hack: I drilled a small hole in the shapes that fill in the main area of
the magnifying glass (the zoomed bit, and also an opaque background beneath this to deal with zooming in on non-opaque content).
Rather than using an Ellipse
I used a Path
with two
EllipseGeometry
objects - one being the size I want, and one tiny one for the mouse to click to. Yuck.
[Update 27th March 2007: This sample has now been updated for the RTM version of WPF. This enables the visibility property to be bound to the checkbox directly. It also fixes the rendering bug.]
[Update 28th March 2007: If you just want to play with the example, rather than downloading the code, here's an XBAP version.]