Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在给定区域而不是整个WPF控件上使evisual()无效?_Wpf_User Interface_Rendering - Fatal编程技术网

是否可以在给定区域而不是整个WPF控件上使evisual()无效?

是否可以在给定区域而不是整个WPF控件上使evisual()无效?,wpf,user-interface,rendering,Wpf,User Interface,Rendering,我有一个复杂的WPF控件,它在OnRender中绘制了很多基本体(有点像地图)。当其中一小部分发生更改时,我只想为受影响的元素重新发出渲染命令,而不是运行整个OnRender。虽然我对OnRender函数在调整大小或其他方面的性能很满意,但对于基于鼠标悬停的基本体高亮显示来说,它的速度还不够快 目前,我知道如何强制屏幕更新的唯一方法是调用InvalidateVisual()。无法发送脏rect区域以使其无效 WPF屏幕组成的最低粒度是UI元素吗?我是否需要将基本体渲染到中间目标,然后使用Inva

我有一个复杂的WPF控件,它在OnRender中绘制了很多基本体(有点像地图)。当其中一小部分发生更改时,我只想为受影响的元素重新发出渲染命令,而不是运行整个OnRender。虽然我对OnRender函数在调整大小或其他方面的性能很满意,但对于基于鼠标悬停的基本体高亮显示来说,它的速度还不够快

目前,我知道如何强制屏幕更新的唯一方法是调用InvalidateVisual()。无法发送脏rect区域以使其无效


WPF屏幕组成的最低粒度是UI元素吗?我是否需要将基本体渲染到中间目标,然后使用InvalidateVisual()将其更新到屏幕上?

WPF的工作方式与此不同,因此无法使区域无效。但是,可以进行一些优化。有一个测量、排列,然后渲染过程。如果控件移动,但实际渲染的内容不变,则可以告诉WPF仅执行排列过程。您可以使用FrameworkPropertyMetadata和FrameworkPropertyMetadataOptions()触发这些依赖项属性值更改无效。

当您想编写WPF自定义/复合控件时,应尽量避免重写OnRender,特别是如果您计划使其部分无效。使用AddVisualChild+override VisualChildrenCount+override GetVisualChild+override Measure和排列方式更容易(包含两个子项的伪代码):


使用这种代码,您可以使用类似subcrolx.InvalidateXXX()的命令使一部分无效

除非控件的大小发生变化,否则不应使用
InvalidateVisual()
,因为它会导致相当昂贵的UI重新布局

WPF是一个保留的绘图系统。这意味着
OnRender()
最好调用
AccumeratedRawingObjects()
。它实际上是在累积一个动态图形对象树,每个布局只需要发生一次。然后,它会在需要时使用这些对象来绘制UI。要在不重新布局的情况下更改部分UI的外观,可以在
OnRender()
之后随时更新某些对象(如DrawingGroup、RenderTargetBitmap和WriteableBitmap)

要在以后更新部分UI,请将这些命令包装在
DrawingGroup
中,并将该对象放入
DrawingContext
中。然后您可以
Open()
并随时更新它,WPF将自动重新绘制UI的该部分

这就是它看起来的样子:

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

是否覆盖UIElement.OnRender以绘制UIElement内的所有内容,或者该元素是否仍具有正常的视觉子元素?
MeasureCore
ArrangeCore
不可覆盖。也许你想说
MeasureOverride
ArrangeOverride
?@dotnet-这取决于你是从UIElement还是FrameworkElement派生的
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();            
}