WPF - Как программно материализовать объект в визуальный контент? - PullRequest
6 голосов
/ 23 августа 2011

Когда вы назначаете объект элементу управления Content, он материализует визуал, соответствующий этому назначенному объекту. Есть ли программный способ добиться того же результата? Я хотел бы вызвать функцию в WPF с объектом и получить обратно Visual, где при генерации Visual применяется та же логика, как если бы вы предоставили объект экземпляру элемента управления Content.

Например, если у меня есть объект POCO, и я назначаю его элементу управления Content, и, как оказалось, определяется соответствующий DataTemplate, он материализует этот шаблон для создания Visual. Я хотел бы, чтобы мой код мог взять объект POCO и получить обратно из WPF Visual.

Есть идеи?

1 Ответ

8 голосов
/ 23 августа 2011

Используйте 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/en-us/library/system.windows.frameworktemplate.loadcontent.aspx

Если у вас есть DataTemplate, определенный для всех экземпляров типа (DataType = {x: Type ...}, но не x: Key = "..."), то вы можете создавать контент, используя соответствующий DataTemplate, используя следующий статический метод. Этот метод также эмулирует ContentControl, возвращая TextBlock, если 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;
}
...