强制 DataTemlate return 特定对象

Force DataTemlate to return a specific object

我正在编写一个新的 WPF 控件来绘制和编辑大量形状,比如数十万个。为此,我想让用户为他的数据定义 DataTemplate。但是 LoadContent 这个特定的 DataTemplate 必须 return 特定的类型,IShape。我怎样才能做到这一点?

首先,模板的全部意义在于支持插入任意 视觉树。如果您对模板的组成有严格的要求,那么使用模板是错误的设计选择。

其次,模板必须描述Visual。如果您要绘制数十万个形状,您 将无法 将它们表示为视觉效果。视觉效果相当重量级

  1. 他们参与了输入命中测试。 (!)
  2. 它们拥有依赖对象的所有开销。
    1. 他们参与继承上下文。
    2. 他们必须将 属性 更改传达给他们的父级,即影响布局和渲染的属性。
    3. 它们可能包含动态资源引用,它们必须观察变化。
  3. 它们可能会延长更重的 UIElement 甚至更重的 FrameworkElement,这意味着:
    1. 他们参与布局。 (!)
    2. 路由事件通过它们传递,并可能由它们处理。
    3. 他们可能正在使用数据绑定。

作为替代方案,我建议您提供一个界面,您可以通过该界面提供 几何数据 ,您可以冻结、共享、重用和高效渲染这些数据。这将允许您坚持使用 WPF 中可用的最低级别的图形 API 集。但是,老实说,即使那样也可能不够好。

但有一件事是肯定的:在 Visual Layer 中呈现所有这些形状是不可能的。我至少会实施某种形式的虚拟化,您可以在其中有效地仅定位视图中的那些形状(四叉树或类似的?),仅渲染视图中的几何体(使用裁剪),并使用缓存合成来避免不断重绘;重新镶嵌;如果实际上没有任何变化,则对几何体执行每个图元抗锯齿。

DataTemplate return 模板内容的根元素的 LoadContent 方法。所以它只会 return 一个 IShape 如果用户(消费者)已经准确地将 IShape 定义为模板中的根元素。

但是您不能真正强制 class 的消费者将 DataTemplate 类型的 属性 设置为 DataTemplate 保证包含 IShape。消费者不妨将 属性 设置为仅包含 Button.

DataTemplate

你可以做的是在运行时抛出一个InvalidOperationException,如果LoadContent方法[=47] =]s 除了 IShape 以外的任何东西。但是,您不能在编译时做出任何保证。但这就是 DataTemplates 的工作方式。

也许您应该考虑让用户设置 IShape 属性 而不是 DataTemplate 属性。您可以让 IShape(或 Shape)成为某种 ContentControlUserControl

毕竟,DataTemplate 是一个可能包含任何 UIElement.

模板