如何在WPF中使用OnRender事件,但只渲染到控件区域?

3

背景:
我正在将一个控件从WinForms转换到WPF。在WinForms中,我覆盖了一个PictureBox并使用OnPaint事件来绘制我需要的内容到该控件。该控件会处理所有的双缓冲和剪切。

我将该控件转换为WPF,并且现在从Canvas继承。我正在覆盖OnRender事件,并将所有内容绘制到DrawingContext上,但看起来DrawingContext允许我将图形绘制到控件之外,进入视图的其他部分:

Render example

在上面的图片中,实心深粉色框是控件,浅粉色框和绿线都在(0, 0)处绘制,但蓝色框绘制在(0, -100)处。

在WinForms中,PictureBox会剪切掉不在控件区域内的任何内容。

此外,我发现如果方框下降到控件以下,则蓝色方框确实被剪切了。我认为这是因为它确实被剪切到了封闭Grid的下面,但我不确定。

问题:

  1. DrawingContext到底在做什么,为什么我可以在控件之外进行绘制?
  2. 如何在WPF中实现相同的功能并进行正确的剪切?我需要覆盖不同的函数、以不同的方式绘制,还是有一些方法可以将我的控件的绘制限制在特定区域内的OnRender方法中?
  3. 是否有更好的方法来实现我正在尝试做的事情(对控件进行任意绘制,并进行正确的剪切和双缓冲)?

我尝试向Canvas子元素添加形状,但这非常慢。


只是一点提示:为了通过覆盖OnRender实现自定义渲染,您不需要从Canvas派生。FrameworkElement或者UIElement应该就足够了。但是,您需要将ClipToBounds设置为true。 - Clemens
@Clemens,如果我覆盖其中任何一个,它会处理双缓冲吗?在WinForms中,如果我覆盖了Panel控件,就没有双缓冲,但是PictureBox已经在控件中处理了双缓冲。我将使用此控件作为CAD视图,允许用户通过缩放和平移等操作在其中移动和更改内容。 - Mike Webb
WPF 中没有内置的双缓冲。请参见此处 - Clemens
1个回答

3

这个问题与Canvas如何渲染内容有关。这意味着它的子元素可以在其实际区域之外进行渲染。但是您可以通过设置属性ClipToBoundstrue来避免这种默认行为:

yourCanvas.ClipToBounds = true;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接