Charles Petzold



Curved ScrollBars using WPF 3D

August 26, 2008
New York, N.Y.

Sometimes I get a blog comment a year or so after the original blog entry, and I never know what to do with it. Any "conversation" that might have been taking place about the blog entry has long since subsided, and everyone (including myself) has moved on.

My blog entry Non-Affine Transforms in 2D? posted a year ago is about using WPF 3D to mimic two-dimensional non-affine transforms, which are not otherwise supported in WPF. Recently someone posted a comment asking if a curved slider is possible.

Yes, curved sliders are possible, but it's a rather different process: Curved sliders (and other controls) became possible with .NET 3.5 and the Viewport2DVisual3D class. This class allows you to put an interactive control on the surface of a 3D figure, quite possibly distorting the appearance of the control in the process.

Viewport2DVisual3D derives from Visual3D and thus can be a child of a Viewport3D. The Viewport2DVisual3D class defines Geometry and Material properties like GeometryModel3D to let you define a 3D figure. But Viewport2DVisual3D also defines a Visual property of type Visual that you generally set to a control. (Visual is the content property of Viewport2DVisual3D so in XAML the control often appears as a child of the Viewport2DVisual3D object.)

Viewport2DVisual3D also defines an attached property named IsVisualHostMaterial which you use to indicate that the Material object set to the Material property of the Viewport2DVisual3D plays the role of a host to the Visual object.

The result is a control that conforms to the surface of of a 3D figure (much like a VisualBrush) but is also interactive.

There are several requirements to using Viewport2DVisual3D:

If you're just interested in distorting the appearance of a standard control, you can define a flat 3D figure that resides entirely in the XY plane of 3D space. That's what the following XAML file does to display a curved ScrollBar:

CurvedScrollBar1.xaml

The file puts both the Viewport3D and a TextBlock showing the value of the ScrollBar in a single-cell Grid so the ScrollBar seems to wrap around the TextBlock:

The 3D figure hosting the control need not be flat. The following XAML file defines a curved band also hosting ar ScrollBar:

CurvedScrollBar2.xaml

Here's what that one looks like: