Christian Ruppert
Christian Ruppert

Reputation: 3779

WPF - Auto formatting custom types how? (ControlTemplate, Style..)

EDIT: Solution in code can be found on bottom.

I am not sure if I am "thinking wrong". Assume I have a ListBox, and I want to add different stuff to this ListBox. Of course, I know I could change the ItemTemplate, add some data binding to it, to display my custom classes.

But this is to "special". I am looking for a way to create a "default" look for my DataWrapper, independent on where it is used.

If I try to create a style for it, he is complaining that the class does not descend from FrameworkElement. Ok, easy way, make DataWrapper child of FrameworkElement. But this "feels wrong", as this is a business object, not a UI element.

I am a little bit stuck, I know there must be a way to tell WPF how to render elements it does not know. Currently it displays the full class name.

So what is the simplest way to get e.g. the DataWrapper as TextBlock with green background, the DataWrapper2 as TextBlock with blue background. Displaying the Data string. I know binding and all this stuff, I am just stuck with how to tell WPF:

If one of your children is a DataWrapper, please render it this way. If it is DataWrapper2, please render this way...

Here some tryout code:

public class DataWrapper
{
    public string Data { get; set; }
}

public class DataWrapper2
{
    public string Data { get; set; }
}

public static class ListBoxTest
{
    public static ListBox CreateTestInstance()
    {
        var lB = new ListBox();

        var items = new ObservableCollection<object>
                        {
                            23.5,
                            "Hello World",
                            new Button() {Content = "Click me"},
                            new DataWrapper() {Data = "Some text"},
                            new DataWrapper2() {Data = "Other text"},
                            "string again"
                        };

        lB.ItemsSource = items;

        var dT = CreateDataTemplate();

        lB.Resources.Add(dT.DataTemplateKey, dT);
        return lB;
    }

    public static DataTemplate CreateDataTemplate()
    {
        var dT = new DataTemplate(typeof(DataWrapper));
        var elementFactory = new FrameworkElementFactory(typeof(TextBlock));
        elementFactory.SetBinding(TextBlock.TextProperty, new Binding("Data"));

        dT.VisualTree = elementFactory;

        return dT;
    }
}

Upvotes: 1

Views: 180

Answers (1)

itowlson
itowlson

Reputation: 74802

See DataTemplate.DataType. From the docs: "When you set this property to the data type without specifying an x:Key, the DataTemplate gets applied automatically to data objects of that type."

For finer control, you could also use a DataTemplateSelector.

Upvotes: 2

Related Questions