IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Using VisualBrush to Show a Magnifying Glass

Sunday 29 May, 2005, 10:52 PM

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:

Application with magnifying glass

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:

Magnifying glass zoomed in close

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.]

Copyright © 2002-2013, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk