【问题标题】:How to redraw or refresh in OnRender?如何在 OnRender 中重绘或刷新?
【发布时间】:2012-05-14 14:14:04
【问题描述】:

我想动态地绘制一些东西。以下代码显示了我的 OnRender。我在我的程序中需要它的某个地方设置了 DrawItem。但是当我调用DrawItem =5; 时,我必须调用什么,以便调用 OnRender?

protected override void OnRender(DrawingContext drawingContext)
{
    switch (DrawItem)
    {
        case 1:
            //Draw Item 
            break;
        case 2:
            //Draw Item 
            break;
        case 3:
            //Draw Item 
            break;
        case 4:
            //Draw Item 
            break;
        case 5:
            //Draw Item 
            break;
    }
    base.OnRender(drawingContext)
}

public int DrawItem { get; set; }

【问题讨论】:

    标签: c# wpf drawing onrender


    【解决方案1】:

    如果控件的大小发生变化,您可以使用InvalidateVisual(),但请记住,这会导致您的 UI 重新布局相当昂贵。如果控件的大小保持不变,则不应调用InvalidateVisual()

    更新 UI 的更有效方法是创建 DrawingGroup“后备存储”并将其添加到 DrawingContextOnRender() 期间。然后,您可以随时使用DrawingGroup.Open() 更新它,WPF 将更新您的 UI。

    如果这听起来令人困惑,请记住 WPF 是一个保留的绘图系统。这意味着OnRender() 最好称为AccumulateDrawingObjects()。它实际上是在累积一个实时绘图对象树,其中一些(如 DrawingGroup、RenderTargetBitmap 和 WriteableBitmap)可以稍后更新。

    这就是它的样子:

    DrawingGroup backingStore = new DrawingGroup();
    
    protected override void OnRender(DrawingContext drawingContext) {      
        base.OnRender(drawingContext);            
    
        Render(); // put content into our backingStore
        drawingContext.DrawDrawing(backingStore);
    }
    
    // I can call this anytime, and it'll update my visual drawing
    // without ever triggering layout or OnRender()
    private void Render() {            
        var drawingContext = backingStore.Open();
        Render(drawingContext);
        drawingContext.Close();            
    }
    

    【讨论】:

      【解决方案2】:

      您的问题不清楚,但据我所知,您似乎在要求一种方法来更新绘图变量后刷新视觉效果。更新绘图变量后,您可以使用以下内容:

      this.InvalidateVisual();
      

      和属性:

      private int drawItem;
      pulic int DrawItem
      {
       get {return drawItem;}
       set 
       {
          drawItem=value;
          this.InvalidateVisual();
       }
      }
      

      【讨论】:

        【解决方案3】:

        我遇到了类似的问题,并找到了一个更优雅的解决方案。像这样定义一个 DependencyProperty:

        public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(PropertyType), typeof(PropertyElementType), new FrameworkPropertyMetadata(DefaultPropertyValue, FrameworkPropertyMetadataOptions.AffectsRender));
        

        这里的关键是:

        FrameworkPropertyMetadataOptions.AffectsRender
        

        所以现在可以在 XAML 中设置属性并在更改时自动更新视觉对象。

        【讨论】:

          【解决方案4】:

          http://msdn.microsoft.com/de-de/library/ms598919(v=vs.100).aspx

          您必须为要更新的控件调用 InvalidateVisual。但是正如您所读到的,对 InvalidateVisual 的调用会导致一个完整的布局周期,因此出于性能原因,请确保您的画布或您想要绘制的任何内容不包含或仅包含几个子元素。

          【讨论】:

            猜你喜欢
            • 2011-02-05
            • 2019-08-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-04-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多