1

我需要将数据模板包装在运行时构建的数据模板中。包装的数据模板是 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);
    }

显然我的数据模板比我上面使用的更复杂。

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

已编辑---

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

    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。

4

2 回答 2

1

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

这个链接可能是一个很好的起点

于 2013-01-28T19:59:50.433 回答
0

You can use XamlWriter (the analog to XamlReader) but it has limitations on what can be properly serialized. Things like event handlers and x:Names cause issues.

**UPDATE

Seeing the additional detail I think you should try reversing your approach. Rather than combining the templates using strings and then trying to turn that into the object you want, you can avoid all the weird parsing restrictions by just creating the user's template as a DataTemplate object and then building your own DataTemplate object around it. Your example code is also using 2 Value Paths, which is going to give you .Value.Value on the inner template Text so check to make sure on your real one that you're ending up with the Paths you want. Here's the basics of your example using the objects instead, with the paths updated to expect a String and display its length:

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 };
于 2013-01-28T19:12:13.687 回答