Skip to content

Commit

Permalink
fix(listview): Fix ItemTemplateSelector not working with Fluent styles
Browse files Browse the repository at this point in the history
Add missing workaround for inner ContentPresenter not automatically using outer ContentControl's ContentTemplateSelector to Fluent ListViewItem style.
  • Loading branch information
davidjohnoliver committed Apr 1, 2021
1 parent 742ccf2 commit 5393841
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,11 @@
<Grid.RenderTransform>
<TranslateTransform x:Name="ContentPresenterTranslateTransform" />
</Grid.RenderTransform>
<!-- Uno workaround: template-bind ContentTemplateSelector because it's not automatically propagated from the ContentControl -->
<ContentPresenter x:Name="ContentPresenter"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Expand Down
3 changes: 2 additions & 1 deletion src/Uno.UI.FluentTheme/themeresources.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14682,7 +14682,8 @@
<Grid.RenderTransform>
<TranslateTransform x:Name="ContentPresenterTranslateTransform" />
</Grid.RenderTransform>
<ContentPresenter x:Name="ContentPresenter" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" />
<!-- Uno workaround: template-bind ContentTemplateSelector because it's not automatically propagated from the ContentControl -->
<ContentPresenter x:Name="ContentPresenter" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" />
</Grid>
<!-- The 'Xg' text simulates the amount of space one line of text will occupy.
In the DataPlaceholder state, the Content is not loaded yet so we
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
using Windows.UI.Xaml.Media;
using FluentAssertions;
using FluentAssertions.Execution;
using Uno.Extensions;
using Uno.UI.RuntimeTests.Helpers;

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
{
Expand All @@ -48,6 +50,10 @@ public partial class Given_ListViewBase

private ItemsPanelTemplate NoCacheItemsStackPanel => _testsResources["NoCacheItemsStackPanel"] as ItemsPanelTemplate;

private DataTemplate SelectableItemTemplateA => _testsResources["SelectableItemTemplateA"] as DataTemplate;
private DataTemplate SelectableItemTemplateB => _testsResources["SelectableItemTemplateB"] as DataTemplate;
private DataTemplate SelectableItemTemplateC => _testsResources["SelectableItemTemplateC"] as DataTemplate;

[TestInitialize]
public void Init()
{
Expand Down Expand Up @@ -939,7 +945,7 @@ public async Task When_Items_Not_Their_Own_Container()
var container2 = (ListViewItem)list.ContainerFromItem(2);
Assert.AreEqual(2, container2.Content);
var container3 = (ListViewItem)list.ContainerFromIndex(2);
Assert.AreEqual(3, container3.Content);
Assert.AreEqual(3, container3.Content);
Assert.AreEqual(2, list.IndexFromContainer(container3));
Assert.AreEqual(2, list.ItemFromContainer(container2));
}
Expand Down Expand Up @@ -1176,12 +1182,59 @@ public async Task When_Items_Not_Their_Own_Container_In_OnItemsChanged_Reset()
var container2 = (ListViewItem)list.ContainerFromItem(newItems[2]);
Assert.IsNull(container2);
var containerIndex2 = list.ContainerFromIndex(2);
Assert.IsNull(containerIndex2);
Assert.IsNull(containerIndex2);
};

list.ItemsSource = newItems;
}

[TestMethod]
public async Task When_ItemTemplateSelector_Set()
{
var itemsSource = new[] { "item 1", "item 2", "item 3" };
var templateSelector = new KeyedTemplateSelector
{
Templates = {
{ itemsSource[0], SelectableItemTemplateA },
{ itemsSource[1], SelectableItemTemplateB },
{ itemsSource[2], SelectableItemTemplateC },
}
};

var list = new ListView
{
ItemsSource = itemsSource,
ItemTemplateSelector = templateSelector
};

WindowHelper.WindowContent = list;
await WindowHelper.WaitForLoaded(list);

var container1 = await WindowHelper.WaitForNonNull(() => list.ContainerFromIndex(0) as ListViewItem);
var text1 = container1.FindFirstChild<TextBlock>(tb => tb.Name == "TextBlockInTemplate");
Assert.IsNotNull(text1);
Assert.AreEqual(text1.Text, "Selectable A");

var container2 = await WindowHelper.WaitForNonNull(() => list.ContainerFromIndex(1) as ListViewItem);
var text2 = container2.FindFirstChild<TextBlock>(tb => tb.Name == "TextBlockInTemplate");
Assert.IsNotNull(text2);
Assert.AreEqual(text2.Text, "Selectable B");

var container3 = await WindowHelper.WaitForNonNull(() => list.ContainerFromIndex(2) as ListViewItem);
var text3 = container3.FindFirstChild<TextBlock>(tb => tb.Name == "TextBlockInTemplate");
Assert.IsNotNull(text3);
Assert.AreEqual(text3.Text, "Selectable C");
}

[TestMethod]
public async Task When_ItemTemplateSelector_Set_And_Fluent()
{
using(StyleHelper.UseFluentStyles())
{
await When_ItemTemplateSelector_Set();
}
}

private bool ApproxEquals(double value1, double value2) => Math.Abs(value1 - value2) <= 2;
}

Expand All @@ -1195,4 +1248,11 @@ protected override void OnItemsChanged(object e)
ItemsChangedAction?.Invoke();
}
}

public class KeyedTemplateSelector : DataTemplateSelector
{
public IDictionary<object, DataTemplate> Templates { get; } = new Dictionary<object, DataTemplate>();

protected override DataTemplate SelectTemplateCore(object item) => Templates.UnoGetValueOrDefault(item);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@
<TextBlock Text="{Binding}" />
</local:CounterGrid>
</DataTemplate>
<DataTemplate x:Key="SelectableItemTemplateA">
<TextBlock x:Name="TextBlockInTemplate"
Text="Selectable A" />
</DataTemplate>
<DataTemplate x:Key="SelectableItemTemplateB">
<TextBlock x:Name="TextBlockInTemplate"
Text="Selectable B" />
</DataTemplate>
<DataTemplate x:Key="SelectableItemTemplateC">
<TextBlock x:Name="TextBlockInTemplate"
Text="Selectable C" />
</DataTemplate>
<DataTemplate x:Key="DataContextBindingDataTemplate">
<Grid DataContext="{Binding SignIn}">
<TextBlock Text="{Binding UserName}" />
Expand Down

0 comments on commit 5393841

Please sign in to comment.