c# - 如何以编程方式检索用于 UI 层次结构中特定元素的 DataTemplate?

标签 c# wpf datatemplate code-behind

在给定特定数据类型和该元素的情况下,我们需要在代码中确定哪个模板将自动应用于绑定(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/

相关文章:

c# - XAML 中有没有一种方法可以在双击时选择文本框中的所有文本?

silverlight - 从 DataTemplate 中绑定(bind)?

windows-phone-7 - 在 ContextMenu.MenuItem DataTemplate 中使用 ScrollViewer

c# - 使用 ASP.NET MVC 将 html 表导出到 Excel 文件

c# - 如何将 Type 变量发送到通用方法?

c# - MVVM:如何只将属性读入 ViewModel?

wpf - 如何在 Prism 中使用数据模板

c# - LogicalOperationStack 是否与.Net 4.5 中的异步不兼容

c# - 如何从 FileStream 报告进度

wpf - VS2010 : Error in Adding Reference of Project 1 into Project 2 and Vice Versa