强制DataTemlate返回一个特定的对象

强制DataTemlate返回一个特定的对象

问题描述:

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

+0

DataTemplate的LoadContent方法返回模板中的根元素。 – mm8

+0

@ mm8我想强制这个模板的根为'IShape'类型。 – melmi

+0

你无法执行此操作。看到我的答案。 – mm8

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

其次,模板必须描述一个Visual。如果您要绘制数十万个形状,您不会将表示为视觉效果。视觉相当重

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

作为替代方案,建议你提供,通过它可以被馈送几何数据,你可以冻结,共享,再利用,并有效地呈现的接口。这将允许您坚持使用WPF中最低级别的图形API集。但是,说实话,即使这可能不够好。

虽然有一件事是肯定的:在Visual Layer中呈现所有这些形状是不可能的。至少,我会实现某种形式的虚拟化,在这种形式下,您只能有效地定位那些在视图中的形状(四叉树或类似的形状),仅渲染视图中的几何体(使用剪切),并使用缓存合成来避免不断重绘;再嵌纹;并且如果什么都没有实际改变,则对几何体执行每原始抗锯齿。

+1

Upvoted。性能方面的考虑是我在回答中未涉及的另一方面。 – mm8

LoadContent方法DataTemplate返回模板内容的根元素。因此,如果用户(消费者)已经将模板中的根元素作为IShape进行了临时定义,它将仅返回IShape

但你真的不能强迫你的类的消费者DataTemplate类型的属性设置为这是保证包括IShape一个DataTemplate。消费者也可以将该物业设置为DataTemplate,其中只包含Button

你可以做的是抛出一个InvalidOperationException,在运行,在你的类,如果LoadContent方法返回任何东西比其他IShape。尽管如此,你不能在编译时做任何保证。但这是DataTemplates的工作方式。

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

毕竟,DataTemplate模板可能包含任何UIElement