我想动态地画一些东西。以下代码显示了我的 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; }
如果控件的大小发生更改,则可以使用 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();
}
您的问题尚不清楚,但据我所知,您似乎在要求一种在更新绘图变量后刷新视觉效果的方法。更新图形变量后,可以使用以下内容:
this.InvalidateVisual();
和属性:
private int drawItem;
pulic int DrawItem
{
get {return drawItem;}
set
{
drawItem=value;
this.InvalidateVisual();
}
}
我遇到了类似的问题,并找到了更优雅的解决方案。定义一个依赖属性,如下所示:
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(PropertyType), typeof(PropertyElementType), new FrameworkPropertyMetadata(DefaultPropertyValue, FrameworkPropertyMetadataOptions.AffectsRender));
这里的关键是:
FrameworkPropertyMetadataOptions.AffectsRender
因此,现在可以在 XAML 中设置该属性,并在更改时自动更新视觉对象。
http://msdn.microsoft.com/de-de/library/ms598919(v=vs.100).aspx
您必须为应更新的控件调用 InvalidateVisual。但正如您所读到的,对 InvalidateVisual 的调用会导致完整的布局周期,因此出于性能原因,请确保画布或要绘制的任何内容不包含或仅包含几个子元素。