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;
}