我编写了一个控件,它从FrameworkElement派生了一个类并覆盖了它的OnRender方法。在此方法中,通过向drawingContext.DrawLine方法提供AnimationClock实例,有一个DrawLine动画。
如果只有几行,它就能很好地工作,如果有数百行,它就不再起作用了。 AffectsRender和InvalideVisual()方法也不起作用,它无法调用OnRender方法。如果有一个中等数量的行,它不起作用,但如果我调整窗口的大小,它的工作原理!我发现如果我更改DependencyProperty(它有AffectsRender标志)并同时添加一个新的视觉效果,无论窗口中有多少行,它都可以工作。
我查了一些文章说WPF是一个保留的图形,而WPF本身也调用了OnRender方法。 WPF确定何时需要调用OnRender。如何告诉WPF调用OnRender?
以下是代码:
class PipeLine:FrameworkElement
{
static PipeLine()
{
SignalInputProperty = DependencyProperty.Register("SignalInput", typeof(int), typeof(PipeLine),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
SignalOutputProperty = DependencyProperty.Register("SignalOutput", typeof(bool), typeof(PipeLine),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
}
public static readonly DependencyProperty SignalInputProperty;
public int SignalInput
{
get { return (int)GetValue(SignalInputProperty); }
set
{
SetValue(SignalInputProperty, value);
}
}
public static readonly DependencyProperty SignalOutputProperty;
public bool SignalOutput
{
get { return (bool)GetValue(SignalOutputProperty); }
set { SetValue(SignalOutputProperty, value); }
}
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
base.OnRender(drawingContext);
Point startPH = new Point(0, ActualHeight / 2);
Point endPH = new Point(ActualWidth, ActualHeight / 2);
Point startPH1 = new Point(-this.ActualHeight / 2, this.ActualHeight / 2);
Point endPH1 = new Point(this.ActualWidth + this.ActualHeight / 2, this.ActualHeight / 2);
PointAnimation animation = new PointAnimation();
animation.From = startPH;
animation.To = endPH;
animation.Duration = new Duration(TimeSpan.FromSeconds(2.0));
AnimationClock clock = animation.CreateClock();
Pen pen1 = new Pen(Brushes.DarkGray, ActualHeight);
Pen pen2 = new Pen(Brushes.LightSkyBlue, ActualHeight);
if (SignalInput == 2 && !SignalOutput)
{
drawingContext.DrawLine(pen1, startPH, endPH);
drawingContext.DrawLine(pen2, startPH, null, endPH, clock);
}
else
{
drawingContext.DrawLine(pen1, startPH, endPH);
SignalOutput = false;
}
}
void clock_Completed(object sender, EventArgs e)
{
this.SignalOutput = true;
}
}
答案 0 :(得分:0)
在WPF中,在发生排列或测量时调用OnRender方法。所以我想这是你问题第二部分的答案。
答案 1 :(得分:0)
问题是SignalOutput值不会改变。 它在第一个滴答声时变为True。 然后它一次又一次成真。
如果OldValue == NewValue,则不会更新依赖项属性。
因此DP不会影响渲染,因为它本身并未受到影响。
void clock_Completed(object sender, EventArgs e)
{
this.InvalidateVisual();
}