WPF - 如何通过编程将对象实体化为可视内容?

6
当您将一个对象分配给内容控件时,它会实现适用于该指定对象的可视化。是否有一种编程方式可以实现相同的结果?我想调用WPF中的一个函数,并使用一个对象获取一个Visual,其中应用与将对象提供给Content控件实例相同的逻辑以生成Visual。
例如,如果我有一个POCO对象,并将其分配给一个Content控件,如果有一个合适的DataTemplate定义,那么它将实现该模板来创建Visual。我希望我的代码能够接受一个POCO对象,并从WPF获取Visual。
有什么想法吗?
1个回答

9
使用 DataTemplate.LoadContent()。示例:
DataTemplate dataTemplate = this.Resources["MyDataTemplate"] as DataTemplate;
FrameworkElement frameworkElement = dataTemplate.LoadContent() as FrameworkElement;
frameworkElement.DataContext = myPOCOInstance;

LayoutRoot.Children.Add(frameworkElement);

http://msdn.microsoft.com/zh-cn/library/system.windows.frameworktemplate.loadcontent.aspx

如果您为所有类型实例定义了一个 DataTemplate(DataType={x:Type ...},但没有 x:Key="..."),则可以使用以下静态方法使用适当的 DataTemplate 创建内容。此方法还通过返回 TextBlock 来模拟 ContentControl,如果未找到 DataTemplate。

/// <summary>
/// Create content for an object based on a DataType scoped DataTemplate
/// </summary>
/// <param name="sourceObject">Object to create the content from</param>
/// <param name="resourceDictionary">ResourceDictionary to search for the DataTemplate</param>
/// <returns>Returns the root element of the content</returns>
public static FrameworkElement CreateFrameworkElementFromObject(object sourceObject, ResourceDictionary resourceDictionary)
{
    // Find a DataTemplate defined for the DataType
    DataTemplate dataTemplate = resourceDictionary[new DataTemplateKey(sourceObject.GetType())] as DataTemplate;
    if (dataTemplate != null)
    {
        // Load the content for the DataTemplate
        FrameworkElement frameworkElement = dataTemplate.LoadContent() as FrameworkElement;

        // Set the DataContext of the loaded content to the supplied object
        frameworkElement.DataContext = sourceObject;

        // Return the content
        return frameworkElement;
    }

    // Return a TextBlock if no DataTemplate is found for the source object data type
    TextBlock textBlock = new TextBlock();
    Binding binding = new Binding(String.Empty);
    binding.Source = sourceObject;
    textBlock.SetBinding(TextBlock.TextProperty, binding);
    return textBlock;
}

我想要的东西与Content类完全相同,即遵循Content控件本身的相同逻辑。你的代码很好,对于DataTemplate场景来说也很好。但是我的POCO可能没有定义DataTemplate。 - Phil Wright
如果没有匹配的DataTemplate,则会回退到创建一个TextBlock,并在POCO对象上使用ToString()来定义文本。 - Phil Wright
很简单,我刚刚更新了方法,现在会创建一个TextBox而不是返回null(如果没有找到DataTemplate)。顺便提一下,ContentControl会将UIElement内容显示为UIElement,因此如果您已经有一个UIElement作为内容,请勿使用此方法。 - Harlow Burgess
问题在于内部绑定不起作用,所有控件都未绑定。 - Shimmy Weitzhandler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接