2013-03-24 11 views
9

Próbuję utworzyć reprezentację wizualną dowolnego algorytmu sortowania, w którym dane są reprezentowane w tablicy int []. Przykładem sortowanie bąbelkowe na wikipedii:Jak odświeżyć płótno

Bubble sort from wikipedia

Moi algorytmów sortowania wszystkie podnieść zdarzenie ItemsSwapped gdy dwie pozycje w int [] tablicy są zamienione. Próbuję wyświetlić dane po każdym zdarzeniu na płótnie, to mój kod:

// Handler for ItemsSwapped event. 
private void Render(object sender, ItemsSwapEventArgs e) 
{ 
    canvas.Children.Clear(); 
    int numberOfElements = e.Data.Length; 

    for (int x = 0; x < numberOfElements; x++) 
    { 
     RenderValue(x, e.Data[x]); 
    } 
    // Here I should somehow refresh canvas. 
} 

private void RenderValue(int x, int y) 
{ 
    var value = new Ellipse 
        { 
         Width = 5, 
         Height = 5, 
         Stroke = Brushes.Black, 
         StrokeThickness = 2, 
        }; 
    Canvas.SetTop(value, x); 
    Canvas.SetLeft(value, y); 
    canvas.Children.Add(value); 
} 

Problem polega na tym, że płótno nie odświeża się, to po prostu wyświetla ostatecznego rozwiązania po pewnym czasie. Jak mogę go odświeżyć po każdym wywołanym wydarzeniu?

Edycja - próbowałem przy użyciu obiektu UpdateLayout, InvalidateMeasure and Dispatcher, ale nie działało.

Odpowiedz

2

Może uruchomisz algorytm sortowania w wątku interfejsu użytkownika, więc nie zaktualizuje się, dopóki nie zostanie ukończony. Spróbuj posortować w innym wątku i zaktualizuj dzieci z programu Canvas, używając Dispatcher, dzwoniąc pod numer Invoke lub BeginInvoke.

Jeśli handler ItemsSwapped jest wywoływana z osobnym wątku, może to wyglądać tak:

private void Render(object sender, ItemsSwapEventArgs e) 
{ 
    Dispatcher.Invoke((Action)(() => 
     { 
      canvas.Children.Clear(); 
      int numberOfElements = e.Data.Length; 

      for (int x = 0; x < numberOfElements; x++) 
      { 
       RenderValue(x, e.Data[x]); 
      } 
     })); 
}