Tworzę własny FrameworkElement
i zastępuję VisualChildrenCount{get;}
i GetVisualChild(int index)
, zwracając moją własną instancję DrawingVisual
.RysunekVisual nie jest odświeżany
Jeśli zmodyfikuję zawartość obrazu po wstępnym renderowaniu (np. W programie obsługi czasomierza), używając DrawingVisual.RenderOpen()
i rysując do kontekstu, element nie zostanie odświeżony.
Oto najprostszy przykład:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
namespace VisualTest
{
public class TestControl : FrameworkElement
{
private readonly DrawingVisual _visual = new DrawingVisual();
public TestControl()
{
Draw(false);
var timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 2)};
timer.Tick += (sender, args) =>
{
Draw(true);
InvalidateVisual();
timer.Stop();
};
timer.Start();
}
protected override Visual GetVisualChild(int index)
{
return _visual;
}
protected override int VisualChildrenCount
{
get { return 1; }
}
private void Draw(bool second)
{
DrawingContext ctx = _visual.RenderOpen();
if (!second)
ctx.DrawRoundedRectangle(Brushes.Green, null, new Rect(0, 0, 200, 200), 20, 20);
else
ctx.DrawEllipse(Brushes.Red, null, new Point(100, 100), 100, 100);
ctx.Close();
}
}
}
InvalidateVisual()
nic nie robi. Chociaż zmiana rozmiaru okna zawierającego element zostanie zaktualizowana.
Jakieś pomysły na poprawne odświeżenie zawartości? Korzystnie bez wprowadzenie nowych właściwości zależności dla mojego elementu.
Kod ten spowoduje wyciek pamięci, ponieważ jest dodawany do drzewa, ale nigdy nie został usunięty. Lepszym kodem jest dodanie wizualnego na załadowanym zdarzeniu i usunięcie go na rozładowanym zdarzeniu - zobacz moją odpowiedź. – splintor