Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataTemplateSelector for TreeView does not show nested items #994

Closed
knightmeister opened this issue Jul 4, 2019 · 5 comments
Closed

DataTemplateSelector for TreeView does not show nested items #994

knightmeister opened this issue Jul 4, 2019 · 5 comments
Assignees
Labels
area-TreeView team-Controls Issue for the Controls team

Comments

@knightmeister
Copy link

knightmeister commented Jul 4, 2019

Describe the bug
I have noticed a weird behavior using a DataTemplateSelector for a treeview.

See screenshot #1 for the expected behavior.

I went and looked at the XAML Controls Gallery and note that the DataTemplateSelector is set up differently; I would still expect this to work how I've done it.

Steps to reproduce the bug
Here is the code which works as expected:

    <TreeView CanDragItems="False" CanReorderItems="False" ItemsSource="{x:Bind Items}">
        <TreeView.ItemTemplate>
            <DataTemplate x:DataType="local:ItemTest">
                <TreeViewItem ItemsSource="{x:Bind Subitems}" IsExpanded="True">
                    <TreeViewItem.Content>
                        <TextBlock Text="{x:Bind Name}" />
                    </TreeViewItem.Content>
                </TreeViewItem>
            </DataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

I have tried to create a DataTemplateSelector as follows:

Treeview is defined in XAML as:

   <TreeView CanDragItems="False" CanReorderItems="False" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}" ItemsSource="{x:Bind Items}" />

The data template selector code is as follows:

internal class MyDataTemplateSelector : DataTemplateSelector
{
    private static DataTemplate _itemType1Template;
    private static DataTemplate _itemType2Template;

    static MyDataTemplateSelector ()
    {
        var templates = new Templates();
        _itemType1Template= (DataTemplate)templates["item1Template"];
        _itemType2Template= (DataTemplate)templates["item2Template"];
    }
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        if (item is Type1)
            return _itemType1Template;
        else if (item is Type2)
            return _itemType2Template;

        throw new NotSupportedException();
    }
}

NOTE: Creating a new instance of Templates each time the template is selected and returning from that instance shows the same result.

The class Templates is a XAML (with codebehind) ResourceDictionary:

<ResourceDictionary
x:Class="MyApp11.Templates"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp11">

<DataTemplate x:DataType="local:ItemTest" x:Key="item1Template">
    <TreeViewItem ItemsSource="{x:Bind Subitems}" IsExpanded="True">
        <TreeViewItem.Content>
            <TextBlock Text="{x:Bind Name}" />
        </TreeViewItem.Content>
     </TreeViewItem>
</DataTemplate>

<DataTemplate x:DataType="local:ItemTest2" x:Key="item2Template">
    <TreeViewItem ItemsSource="{x:Bind Subitems}" IsExpanded="True">
        <TreeViewItem.Content>
            <TextBlock Text="The other item type" />
        </TreeViewItem.Content>
     </TreeViewItem>
</DataTemplate>

Expected behavior
I would expect that using the resource dictionary & DataTemplateSelector to have the same UI and behavior as doing it directly in XAML.

See Screenshot #2 for how it appears.

Screenshots
Screenshot #1 - expected behavior, as seen when the data template is defined locally without a DataTemplateSelector
image

Screenshot #2 - how it appears using the DataTemplateSelector. Note the lack of children:
image

Version Info
Using Win10 1903, not using MUX explicitly.

@ghost
Copy link

ghost commented Jul 4, 2019

Does the tree view item need the selector as well?

@knightmeister
Copy link
Author

knightmeister commented Jul 4, 2019

Ok, I've fixed this after a few hours and looking at the XAML Controls Gallery source.

The issue is the override method used in DataTemplateSelector;

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
    if (item is Type1)
        return _itemType1Template;
    else if (item is Type2)
        return _itemType2Template;

    throw new NotSupportedException();
}

I was overriding that method.

If I override the other overload of SelectTemplateCore, it works!

protected override DataTemplate SelectTemplateCore(object item)
{
    if (item is Type1)
        return _itemType1Template;
    else if (item is Type2)
        return _itemType2Template;

    throw new NotSupportedException();
}

Looks like there might be a bug in the overload with the DependencyObject?

@jevansaks
Copy link
Member

I believe the two-parameter SelectTemplateCore is deprecated and never called ... @ranjeshj to confirm. We should figure out how to document this better, for sure.

@ranjeshj
Copy link
Contributor

ranjeshj commented Jul 9, 2019

That is correct. The override which passes the container is deprecated. Also in this case, the container is in the template that you are creating now so you cannot get the container passed to you.

@ranjeshj
Copy link
Contributor

ranjeshj commented Jul 9, 2019

@jevansaks jevansaks added the team-Controls Issue for the Controls team label Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-TreeView team-Controls Issue for the Controls team
Projects
None yet
Development

No branches or pull requests

4 participants