【问题标题】:WPF OnRender doesn't workWPF OnRender 不起作用
【发布时间】:2015-01-20 02:00:55
【问题描述】:

我编写了一个从 FrameworkElement 派生类并覆盖其 OnRender 方法的控件。在这个方法内部,通过给drawingContext.DrawLine方法提供一个AnimationClock实例,有一个DrawLine动画。

如果只有几行,它就可以工作,如果有数百行,它就不再工作了。 AffectsRender 和 InvalideVisual() 方法也不起作用,它不能调用 OnRender 方法。如果有中等数量的行,它就不起作用,但如果我调整窗口大小,它就起作用了!而且我发现如果我更改 DependencyProperty(具有 AffectsRender 标志)并同时添加新的视觉效果,无论窗口中有多少行,它都可以工作。

我查阅了一些文章,说 WPF 是保留图形,而 OnRender 方法是由 WPF 本身调用的。 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;
    }
}

【问题讨论】:

  • 不要提供长文本解释,而是添加您尝试过的任何源代码。
  • 另外,比“不起作用”更具体。短语“不起作用”几乎可以表示任何含义。
  • 你有没有解决这个问题?我也有类似的问题。

标签: c# wpf onrender


【解决方案1】:

在 WPF 中 OnRender 方法在 Arrange 或 Measure 发生时被调用。所以我想这是你问题第二部分的答案。

【讨论】:

  • 谢谢。我在这里提出了我的示例代码。你能看到吗?这段代码有问题吗?
【解决方案2】:

问题是 SignalOutput 值没有改变。 它在第一次滴答时得到 True 。 然后它一次又一次地成为现实。

如果 OldValue == NewValue,则不会更新依赖属性。

所以 DP 不会影响渲染,因为它本身没有受到影响。

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

【讨论】:

  • 谢谢。InputSignal 属性是由严重的逻辑手动更改的,如果 InputSignal 为 2,那么它将使用动画绘制一条线。如果动画完成,它会给 SignalOutput 属性一个真值。但是如果 InputSignal 是其他值,它会画一条没有动画的线,并将 SignalOuput 属性设置为 false 值。
  • @RambleInX 可能是 SignalOutput 为 true 并且您再次将其设置为 true ,还是始终为 true false true false ...?
  • SignalOutput 的值由 SignalInput 决定。 SignalInput 的值由我自己确定。也就是说,SignalOutput是我自己决定的,可以是真、真、假...真、假、真...等
  • 再次,如果它是 True 并且您再次将其设置为 True 值没有改变并且 OnRender 没有被调用。如果它是真的,然后是假的,然后是真的,那么 OnRender
猜你喜欢
  • 2011-11-12
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
  • 2017-11-04
  • 2013-02-08
相关资源
最近更新 更多