简体   繁体   English

WPF OnRender不起作用

[英]WPF OnRender doesn't work

I write a control that derived a class from the FrameworkElement and overrode its OnRender method. 我编写了一个从FrameworkElement派生一个类并覆盖其OnRender方法的控件。 Inside this method, there is a DrawLine animation by providing an AnimationClock instance to drawingContext.DrawLine method. 在此方法内,通过为drawingContext.DrawLine方法提供AnimationClock实例,从而实现了DrawLine动画。

It works well if there are only a few lines, and it doesn't work any more if there are hundreds of lines. 如果只有几行,它会很好地工作,而如果有几百行,它就不再工作了。 AffectsRender and InvalideVisual() method also doesn't work, it can't call the OnRender method. AffectsRender和InvalideVisual()方法也不起作用,它无法调用OnRender方法。 If there are a middling number of lines, it doesn't work, but if I resize the window, it works! 如果行数中等,则行不通,但如果我调整窗口大小,则行得通! And I found that if I change the DependencyProperty (which has the AffectsRender flag) and add a new visual at the same time, it works no matter how many lines are in the window. 我发现,如果我更改DependencyProperty(具有AffectsRender标志)并同时添加新的视觉效果,则无论窗口中有多少行,它都可以工作。

I have looked up some articles that said that WPF is a retained graphics and the OnRender method is invoked by WPF itself. 我查阅了一些文章,说WPF是保留的图形,OnRender方法由WPF本身调用。 It is WPF that determine when the OnRender need to be invoked. WPF确定何时需要调用OnRender。 How can I do to tell WPF to invoke OnRender? 如何告诉WPF调用OnRender?

Here are the codes: 以下是代码:

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;
    }
}

In WPF OnRender method is called when Arrange or Measure occurs. 在WPF中,当“安排”或“度量”发生时,将调用OnRender方法。 So I guess this is the answer to second part of your question. 所以我想这是您问题第二部分的答案。

The problem is that SignalOutput value does not change . 问题在于SignalOutput值不会改变。 It gets True on the first tick . 第一次滴答就变为True。 And then it gets true again and again . 然后它一次又一次地成为现实。

A dependency property isn't updated if OldValue == NewValue. 如果OldValue == NewValue,则依赖项属性不会更新。

So the DP does not affect the Render because it was not effected itself. 因此,DP不会影响渲染,因为它本身并未实现。

void clock_Completed(object sender, EventArgs e)
{
    this.InvalidateVisual();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM