WPF is a very graphically intensive API, and due to this very fact, we have different ways to account for graphical data in our applications.
The first manner to render output is using the classes of System.Windows.Shapes. Each of the Shape derived classes (Rectangle, Ellipse, Ploygon, etc) are very useful when you need to incorporate user interactivity in your graphics, as shapes extend UIElement. As you might know, this base class defines numerous mouse-centric events. Thus, if you were to define a Ellipse in XAML, you could capture a MouseEnter event very simply:
Code Snippet
- <Window x:Class="WpfGraphics.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <Ellipse x:Name="myCircle" Height="100" Width="100" Fill="Red" MouseEnter="myCircle_MouseEnter"/>
- </Grid>
- </Window>
The corresponding event handler could then take whatever course of action is required when the user moves the mouse cursor within the boundary of the image.
While shapes are very powerful, you must always be aware that they do come with a high memory footprint. When you look at the inheritance chain of Ellipse and contrast that to the WPF Button, they have much of the same infrastructure! Thus, if you were building some sort of application which needed to plot out 1000s of points of data, and you draw these plot points using the Ellipse, it would be just about as much overhead as drawing 1000 Buttons on the window (more or less).
When you need to generate large amounts of graphical data which does not require any user interactivity, one approach is to use "drawings and geometries". Using classes such as DrawingBrush, you can define a (non-interactive) blog of graphical data by specifying a set of geometry objects. Unlike shapes, geometries have no clue how to render themselves, and are little more than light weight containers which define plot points. Once you have configured a DrawingBrush, you can then assign it to any brush-centric property. For example, this markup will paint the background of a <Grid> with a custom brush object packaged as a resource.
Code Snippet
- <Window x:Class="WpfGraphics.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Window.Resources>
- <DrawingBrush x:Key="myBrush">
- <DrawingBrush.Drawing>
- <GeometryDrawing Brush="MediumBlue">
- <GeometryDrawing.Geometry>
- <GeometryGroup>
- <EllipseGeometry RadiusX="20" RadiusY="45" Center="50,50" />
- <EllipseGeometry RadiusX="45" RadiusY="20" Center="50,50" />
- </GeometryGroup>
- </GeometryDrawing.Geometry>
- <GeometryDrawing.Pen>
- <Pen Thickness="10">
- <Pen.Brush>
- <LinearGradientBrush>
- <GradientStop Offset="0.0" Color="Black" />
- <GradientStop Offset="1.0" Color="Gray" />
- </LinearGradientBrush>
- </Pen.Brush>
- </Pen>
- </GeometryDrawing.Pen>
- </GeometryDrawing>
- </DrawingBrush.Drawing>
- </DrawingBrush>
- </Window.Resources>
- <Grid Background="{StaticResource myBrush}">
- </Grid>
- </Window>
This is great, but now if you needed to interact with the geometries, you would need to do so in code, typically by preforming manual hit testing calculations.
A good middle of the road approach is to the the Path class. While Path is also Shape derived type, it defines a Data property, which can (you guessed it) be set to a set of geometries. This is great when you need to define complex graphical data, which still needs to be interactive as a whole unit. In otherwords, you are not interested in interacting with segments of the path, just the final rendered geometry of the path.
The only downside to working with geometries is the large amount of markup required to generate the data. Thankfully, Expression Design will export any graphical image as a set of paths and geometries when you export the image as a *.xaml file.
The final way to work with graphical data in WPF is to drop down to the "visual layer". This approch is only possible in code, and has a look and feel similar to Windows Forms graphical rendering services. If you need the fastest possible way to render out data, visuals are the typically the way to go (which I won't comment on in this post).
45b692a8-4ea8-47c0-a73c-878abac892c6|1|5.0