1

I am creating a path of Markers to be displayed on a GMapControl in my C#/XAML (WPF) application. The control requires I create a UIElement to be overlaid on the map as a marker. I have created a very simple UserControl for this purpose, as follows:

<UserControl x:Class="Project.Resources.Circle"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Ellipse Width="5" Height="5" Stroke="Red" Fill="Red" />
    </Grid>
</UserControl>

However, when I build the line, creating anything up to 400 instances of this control, my application freezes. Since I can only seem to create UserControl's on the UI thread (and not in a Thread or BackgroundWorker), what can I do to speed up the creation of new Circle instances?

Is there a more lightweight UIElement than a UserControl? Any guidance on this appreciated.

agc93
  • 663
  • 1
  • 7
  • 19
  • How about directly deriving from UIElement and overriding the `OnRender` method? There you would draw your circle into the passed `DrawingContext` instance. – Clemens Apr 29 '14 at 12:45
  • Or you directly use `Ellipse` elements instead of wrapping them in UserControls. – Clemens Apr 29 '14 at 12:47
  • I couldn't use your second suggestion as Ellipse is a sealed class. Fortunately, I tried your first with only a UIElement in the XAML and using OnRender with a drawingContext.DrawEllipse() and the performance is leaps and bounds ahead of a UserControl! Did you want to put that as an answer or shall I? – agc93 Apr 29 '14 at 14:36
  • Something even faster would be to use an Image control. The problem with WPF geometry is that it is tesselated on CPU side. However the Image has it's own disadvantages. – Dmitry Apr 29 '14 at 18:54

1 Answers1

1

You could create a minimal derived UIElement like this:

public class Circle : UIElement
{
    protected override void OnRender(DrawingContext drawingContext)
    {
        const double radius = 2.5;
        drawingContext.DrawEllipse(Brushes.Red, null, new Point(), radius, radius);
    }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268