10000's+ UI elements, bind or draw?
        Posted  
        
            by 
                jpiccolo
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by jpiccolo
        
        
        
        Published on 2012-11-09T19:44:27Z
        Indexed on 
            2012/12/04
            17:05 UTC
        
        
        Read the original article
        Hit count: 211
        
I am drawing a header for a timeline control.
It looks like this:

I go to 0.01 millisecond per line, so for a 10 minute timeline I am looking at drawing 60000 lines + 6000 labels. This takes a while, ~10 seconds. I would like to offload this from the UI thread. My code is currently:
private void drawHeader()
{
  Header.Children.Clear();
  switch (viewLevel)
  {
    case ViewLevel.MilliSeconds100:
        double hWidth = Header.Width;
        this.drawHeaderLines(new TimeSpan(0, 0, 0, 0, 10), 100, 5, hWidth);
        //Was looking into background worker to off load UI
        //backgroundWorker = new BackgroundWorker();
        //backgroundWorker.DoWork += delegate(object sender, DoWorkEventArgs args)
        //                               {
        //                                   this.drawHeaderLines(new TimeSpan(0, 0, 0, 0, 10), 100, 5, hWidth);
        //                               };
        //backgroundWorker.RunWorkerAsync();
        break;
    }
}
private void drawHeaderLines(TimeSpan timeStep, int majorEveryXLine, int distanceBetweenLines, double headerWidth)
{
var currentTime = new TimeSpan(0, 0, 0, 0, 0);
const int everyXLine100 = 10;
double currentX = 0;
var currentLine = 0;
while (currentX < headerWidth)
{
    var l = new Line
                {
                    ToolTip = currentTime.ToString(@"hh\:mm\:ss\.fff"),
                    StrokeThickness = 1,
                    X1 = 0,
                    X2 = 0,
                    Y1 = 30,
                    Y2 = 25
                };
    if (((currentLine % majorEveryXLine) == 0) && currentLine != 0)
    {
        l.StrokeThickness = 2;
        l.Y2 = 15;
        var textBlock = new TextBlock
                            {
                                Text = l.ToolTip.ToString(),
                                FontSize = 8,
                                FontFamily = new FontFamily("Tahoma"),
                                Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255))
                            };
        Canvas.SetLeft(textBlock, (currentX - 22));
        Canvas.SetTop(textBlock, 0);
        Header.Children.Add(textBlock);
    }
    if ((((currentLine % everyXLine100) == 0) && currentLine != 0)
        && (currentLine % majorEveryXLine) != 0)
    {
        l.Y2 = 20;
        var textBlock = new TextBlock
                            {
                                Text = string.Format(".{0}", TimeSpan.Parse(l.ToolTip.ToString()).Milliseconds),
                                                            FontSize = 8,
                                                            FontFamily = new FontFamily("Tahoma"),
                                                            Foreground = new SolidColorBrush(Color.FromRgb(192, 192, 192))
                            };
        Canvas.SetLeft(textBlock, (currentX - 8));
        Canvas.SetTop(textBlock, 8);
        Header.Children.Add(textBlock);
    }
    l.Stroke = new SolidColorBrush(Color.FromRgb(255, 255, 255));
    Header.Children.Add(l);
    Canvas.SetLeft(l, currentX);
    currentX += distanceBetweenLines;
    currentLine++;
    currentTime += timeStep;
}
}
I had looked into BackgroundWorker, except you can't create UI elements on a non-UI thread.
Is it possible at all to do drawHeaderLines in a non-UI thread?
Could I use data binding for drawing the lines? Would this help with UI responsiveness?
I would imagine I can use databinding, but the Styling is probably beyond my current WPF ability (coming from winforms and trying to learn what all these style objects are and binding them).
Would anyone be able to supply a starting point for tempting this out? Or Google a tutorial that would get me started?
© Stack Overflow or respective owner