在给定特定数据类型和该元素的情况下,我们需要在代码中确定哪个模板将自动应用于绑定(bind)元素。
我们不是在寻找 DataTemplateSelector,因为它用于告诉 UI 根据自定义逻辑为给定对象使用哪个模板。相反,我们询问 UI 哪个模板将用于给定的数据类型和 UI 元素。
换句话说,我们正在寻找基于窗口资源部分中定义的模板应用的任何 WPF,这些模板可以被该窗口上控件的资源覆盖,可以通过显式设置来覆盖DataTemplate 或直接在该元素上提供 DataTemplateSelector。
另外,我们尝试了 SelectTemplate 的默认实现,但它返回 null,所以我们也不能走那条路。
一个测试是询问一个没有在 UI 中任何地方定义数据模板或选择器的元素“你将如何显示这个值?”希望它会返回一个 DataTemplate,其中包含 TextBlock 的定义,其中文本属性设置为该对象的 ToString 方法,这是在未定义任何其他内容时默认显示的内容。
最佳答案
Thomas Levesque 未经测试的解决方案对我来说不太适用,但提供了一个很好的起点。在我们的例子中,“容器”参数并不总是在视觉树中,所以首先我们沿着逻辑树向上走,直到找到视觉对象。结合 MarqueIV 的出色建议,得出了一个相当简单的解决方案。
以下代码在生产中对我有用。你的旅费可能会改变。 :)
public static DataTemplate FindTemplateForType(Type dataType, DependencyObject container)
{
var frameworkElement = container as FrameworkElement;
if (frameworkElement != null)
{
var key = new DataTemplateKey(dataType);
var template = frameworkElement.TryFindResource(key) as DataTemplate;
if (template != null)
return template;
}
if (!(container is Visual || container is Visual3D))
{
container = FindClosestVisualParent(container);
return FindTemplateForType(dataType, container);
}
else
{
var parent = VisualTreeHelper.GetParent(container);
if (parent != null)
return FindTemplateForType(dataType, parent);
else
return FindTemplateForType(dataType, Application.Current.Windows[0]);
}
}
public static DependencyObject FindClosestVisualParent(DependencyObject initial)
{
DependencyObject current = initial;
bool found = false;
while (!found)
{
if (current is Visual || current is Visual3D)
{
found = true;
}
else
{
current = LogicalTreeHelper.GetParent(current);
}
}
return current;
}
关于c# - 如何以编程方式检索用于 UI 层次结构中特定元素的 DataTemplate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18539878/