Open nickrandolph opened 1 year ago
Similar issue https://github.com/unoplatform/uno/issues/11926
This is an interesting issue, where in general, the top level element of a DataTemplate
is supposed to be a TreeViewItem
, but in the template from the sample it is not.
The workaround is easy, where the leaf template can be changed to be:
<DataTemplate x:Key="animalTemplate">
<TreeViewItem>
<Border Background="Red"
MinHeight="20"
MinWidth="20">
<TextBlock Text="{Binding Name}" />
</Border>
</TreeViewItem>
</DataTemplate>
Though this means that ItemsControl
, TreeView
or ContentControl
should be handling this specific structure properly and at this point, it's only rendering a ToString of the databound item.
I investigated this using the changed from #14692 and it's still broken. The problem is mainly with the interaction of Content<Control|Presenter>s with ContentTemplateSelector
(which is set from the ItemTemplateSelector of the wrapping ItemsControl like in the sample).
On WinUI (and Uno), something like this works:
<ContentControl Content="1" ContentTemplate="{StaticResource someTemplate}">
</ContentControl>
but this doesn't work:
<ContentControl Content="1" ContentTemplateSelector="{StaticResource someTemplateSelector}">
</ContentControl>
This is a problem in this repro because after materializing the nested element the state of the child TreeViewItem is similar to the example above. In fact, the same problem would happen without nesting. Here's a simpler repro:
<UserControl.Resources>
<DataTemplate x:Key="animalTemplate">
<Border Background="Red" Width="50" Height="50">
<TextBlock Foreground="Green" Text="{Binding}" />
</Border>
</DataTemplate>
<local:TreeItemTemplateSelector x:Key="treeItemTemplateSelector" Template="{StaticResource animalTemplate}" />
</UserControl.Resources>
<StackPanel>
<TreeView x:Name="tvtop" ItemsSource="12" ItemTemplateSelector="{StaticResource treeItemTemplateSelector}" />
</StackPanel>
public class TreeItemTemplateSelector : DataTemplateSelector
{
public DataTemplate Template { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
return Template;
}
}
Everything seems to be set correctly on our side, but we're just not using the ContentTemplateSelector of the problematic TreeViewitem. The logic for selecting the right template and using it in WinUI's source is very non-trivial and the source of truth seems to be the GetSelectedTemplate
method in VirtualizingInformation
, so it's very different to what we're doing. Actually, a lot of things that you'd expect to be working on WinUI actually don't.
We can do many workarounds but they wouldn't be very accurate. The most resonable of them would be to add
SetUpdateTemplate();
in ContentPresenter.OnContentTemplateSelectorChanged
. This would make some sense, but it will still be different from WinUI. For example, Snippet 2
which does NOT work (i.e. ignores the selector and looks weird) on WinUI, will "work" on our side. I think we can settle for this since we will never really match WinUI's behaviour without porting ContentPresenter and/or ContentControl.
Current behavior
When using a datatemplateselector to define different templates for the type of data in each node, nested elements aren't being rendered using the data template.
This works on WinUI eg
This doesn't work on other uno targets (wasm, mobile, skia)
Expected behavior
The correct data template should be applied for each node
How to reproduce it (as minimally and precisely as possible)
UnoApp7.zip
Workaround
No response
Works on UWP/WinUI
None
Environment
No response
NuGet package version(s)
No response
Affected platforms
No response
IDE
No response
IDE version
No response
Relevant plugins
No response
Anything else we need to know?
No response