在运行时更改datatemplate

时间:2013-01-28 19:05:40

标签: wpf

我需要将datatemplate包装在运行时构建的datatemplate中。包装的datatemplate是WPF元素,因为需要在代码中创建包装模板。 类似的东西:

     public DataTemplate GetTemplate(DataTemplate template)
    {
        string xaml = string.Format(@"
<DataTemplate>
    <ContentControl Content=""{{Binding}}"">
        <ContentControl.ContentTemplate>
{0}
        </ContentControl.ContentTemplate>
    </ContentControl>
</DataTemplate>", template);
        return CreateTemplate(xaml);
    }

显然我的datatemplate比我上面使用的那个更复杂。

无论如何我都不知道采用现有的xaml元素并将其转换为字符串。看起来我可以使用FrameworkElementFactory,但我发现它已被删除,这让我觉得我错过了一些明显的东西。

编辑---

我正在做的是创建一个用户将提供datatemplate的控件,但我需要对模板进行更改。也许这个例子会更有意义......

    public DataTemplate GetTemplate2()
    {
        // this template would be supplied by the user
        // I'm creating it here as an example
        string t = string.Format(@"
          <DataTemplate>
            <TextBlock Text=""{{Binding Value}}""/>
        </DataTemplate>");
        T = CreateTemplate(t);

        string xaml = string.Format(@"
<DataTemplate>
    <ContentControl Content=""{{Binding}}"">
        <ContentControl.ContentTemplate>
{0}
        </ContentControl.ContentTemplate>
    </ContentControl>
</DataTemplate>", t);
        return CreateTemplate(xaml);
    }

这一切都有效,因为我正在使用字符串模板(例如t)。但是我需要找出一些方法来使用实际的DataTemplate(例如T)。不幸的是,XamlWriter无法处理Binding。

2 个答案:

答案 0 :(得分:1)

您可以创建DataTemplate选择器。在那里,您可以添加逻辑以在运行时构建DataTemplate。您还可以在DataTemplate选择器中创建dependencyProperty。然后将它在你的xaml中绑定到存储在某个支持模型中的DataTemplate,并且它会做任何事情......

link可能是一个开始的好地方

答案 1 :(得分:0)

您可以使用XamlWriter(类似于XamlReader),但它对可以正确序列化的内容有限制。事件处理程序和x:名称等问题导致问题。

**更新

看到其他细节,我认为你应该尝试扭转你的方法。不是使用字符串组合模板然后尝试将其转换为您想要的对象,而是通过仅将用户的模板创建为DataTemplate对象然后围绕它构建自己的DataTemplate对象来避免所有奇怪的解析限制。您的示例代码也使用2个值路径,它将在内部模板文本上为您提供.Value.Value,因此请检查以确保您的真实路径以您想要的路径结束。以下是使用对象的示例的基础知识,更新路径以期望String并显示其长度:

DataTemplate T = XamlReader.Parse(string.Format(@"
    <DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <TextBlock Text=""{{Binding}}""/>
    </DataTemplate>")) as DataTemplate;

FrameworkElementFactory controlFactory = new FrameworkElementFactory(typeof(ContentControl));
controlFactory.SetBinding(ContentControl.ContentProperty, new Binding("Length"));
controlFactory.SetValue(ContentControl.ContentTemplateProperty, T);

DataTemplate mainTemplate = new DataTemplate { VisualTree = controlFactory };