在运行时组合DataTemplates

我有一个ListBox,它通过ItemSource呈现对象的数据绑定列表。 因为每个对象都有特殊的显示需求,所以我定义了一个ItemTemplateSelector,它根据对象返回相应的DataTemplate。 这一切都顺利进行。

每个对象的DataTemplates遵循一个通用公式,但在中间包含自定义元素。 例如:

           

正如你所看到的那样,有很多共享的XAML,在中间包含一个小的自定义部分。

其他数据模板将由其他工程师编写(他们希望为他们添加的每个新对象类型创建一个),因此我有兴趣创建一个新的DataTemplate,尽可能简单,无痛。 当然,没有复制整个DataTemplate与中间添加的自定义“东西” – 但我也不会偏向于将模板的一部分提取为可重用的部分并引用它们,因为它仍会导致大量重复的代码每个新的DataTemplate,这意味着可能的错误和难以维护。 也就是说,这是一种更易于维护的方法,但仍然感觉不是最理想的:

           [...]          

那么:解决这个问题的最佳策略是什么? AFAIK我坚持使用DataTemplates,因为这是ListBox ItemTemplateSelector接受的唯一元素。 有没有办法在DataTemplateSelector中创建复合DataTemplate? 我将提供由所有对象共享的库存DataTemplate,以及每个对象类型所需的自定义XAML位中的DataTemplateSelector引用。 其他工程师会加入这种通用代码行为。

不确定,在这里黑暗中摸索着是否有一种模式可以让我优雅地解决这个问题。

并且,仅供参考:我当前的DataTemplateSelector非常简单。 这是我期望构建最终DataTemplate的地方,而不是简单地返回在XAML中硬编码的那个。

 public class NodeComponentDataTemplateSelector : DataTemplateSelector { public override DataTemplate SelectTemplate(object item, DependencyObject container) { FrameworkElement element = container as FrameworkElement; if (element != null && item != null) { if (item is CollectibleComponent) return element.FindResource("collectibleTemplate") as DataTemplate; // [...] } } } 

您可以使用XamlReader.Parse或XamlReader.Load方法动态创建DataTemplate ,例如:

 string template = "[PLACEHOLDER]".Replace("[PLACEHOLDER]", "...custom code..."); return System.Windows.Markup.XamlReader.Parse(template) as DataTemplate; 

自定义部件可以定义为UserControls

我担心没有办法将DataTemplate基于纯XAML中的另一个。

您可以创建一个适合您需求的新CustomControl 。 它将自己应用样式,您可以提供额外的DepdendencyProperties以使其更方便。 最后,您仍然可以将它放在DataTemplate ,以便与DataTemplate一起使用。