如何在OnRender中重绘或刷新?
我想动态画画。 以下代码显示了我的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; }
您的问题不明确,但从我能理解的情况来看,您似乎要求在更新绘图变量后刷新视觉效果的方法。 更新绘图变量后,您可以使用以下内容:
this.InvalidateVisual();
和财产:
private int drawItem; pulic int DrawItem { get {return drawItem;} set { drawItem=value; this.InvalidateVisual(); } }
如果控件的大小发生更改,则可以使用InvalidateVisual()
,但请记住,这会导致UI的重新布局相当昂贵。 如果控件的大小保持不变,则不应调用InvalidateVisual()
。
更新UI的一种更有效的方法是创建一个DrawingGroup
“后备存储”,并在OnRender()
期间将其添加到DrawingContext
。 然后,您可以随时使用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(); }
http://msdn.microsoft.com/de-de/library/ms598919(v=vs.100).aspx
您必须为要更新的控件调用InvalidateVisual。 但正如您所读到的,对InvalidateVisual的调用会导致完整的布局循环,因此请确保出于性能原因,您的canvas或您想要绘制的任何内容不包含或仅包含少数子元素。
我遇到了类似的问题,发现了更优雅的解决方案。 像这样定义DependencyProperty:
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(PropertyType), typeof(PropertyElementType), new FrameworkPropertyMetadata(DefaultPropertyValue, FrameworkPropertyMetadataOptions.AffectsRender));
关键在于:
FrameworkPropertyMetadataOptions.AffectsRender
所以现在可以在XAML中设置属性并在更改时自动更新视觉。