Using collection view with mixed types elements ? (heterogeneous collection) #27235
Unanswered
bebenlebricolo
asked this question in
Q&A
Replies: 1 comment 1 reply
-
What's wrong with setting your DataTemplate to a ContentView? You can defined 3 ControlTemplates in a ResourceDictionary and you use one of the ControlTemplate as the default and you can switch on either of the other two with the use of DataTriggers. <!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="MauiCustomView.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiCustomView"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Name="this"
x:DataType="local:MainPage"
BindingContext="{Reference this}">
<ContentPage.Resources>
<ResourceDictionary x:Name="resourceDictionary">
<toolkit:MultiMathExpressionConverter x:Key="MultiMathExpressionConverter" />
<ControlTemplate x:Key="LabelControlTemplate">
<Label Text="Label" />
</ControlTemplate>
<ControlTemplate x:Key="ButtonControlTemplate">
<Button Text="Button" />
</ControlTemplate>
<ControlTemplate x:Key="EntryControlTemplate">
<Entry Placeholder="Entry" />
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<CollectionView ItemsSource="{Binding Widgets}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<ContentView ControlTemplate="{StaticResource LabelControlTemplate}">
<ContentView.Triggers>
<DataTrigger
Binding="{Binding .}"
TargetType="ContentView"
Value="Button">
<Setter Property="ControlTemplate" Value="{StaticResource ButtonControlTemplate}" />
</DataTrigger>
<DataTrigger
Binding="{Binding .}"
TargetType="ContentView"
Value="Entry">
<Setter Property="ControlTemplate" Value="{StaticResource EntryControlTemplate}" />
</DataTrigger>
</ContentView.Triggers>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage> If you don't want to use a DataTrigger, then, you can construct a StringToResourceConverter. <!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="MauiCustomView.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiCustomView"
x:Name="this"
x:DataType="local:MainPage"
BindingContext="{Reference this}">
<ContentPage.Resources>
<ResourceDictionary x:Name="resourceDictionary">
<ControlTemplate x:Key="LabelControlTemplate">
<Label Text="Label" />
</ControlTemplate>
<ControlTemplate x:Key="ButtonControlTemplate">
<Button Text="Button" />
</ControlTemplate>
<ControlTemplate x:Key="EntryControlTemplate">
<Entry Placeholder="Entry" />
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<CollectionView ItemsSource="{Binding Widgets}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<ContentView ControlTemplate="{Binding ., Converter={local:StringToResourceConverter}, ConverterParameter={Reference resourceDictionary}}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage> // MainPage.xaml.cs
using System.Collections.ObjectModel;
using System.Globalization;
namespace MauiCustomView;
public class StringToResourceConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string stringValue && parameter is Microsoft.Maui.Controls.ResourceDictionary resourceDictionary)
{
return resourceDictionary?.TryGetValue($"{stringValue}ControlTemplate", out var resource) == true ? resource : null;
}
return null;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public partial class MainPage : ContentPage
{
public ObservableCollection<string> Widgets { get; } = new ObservableCollection<string>()
{
"Label", "Button", "Entry"
};
public MainPage()
{
InitializeComponent();
}
} If you don't want to use converters, you can use multiple DataTrigger instead. One for each |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi guys !
Lately I've been trying to achieve something that looks like this using heterogeneous data collections :
This is using different data models (one for the date separator, the other one the actual card content).
The interesting part, I believe, lies around the Date separators which can be used to construct a mixed UI.
I saw that something of this sort might be achievable via DataTemplateSelector, and I would like to do it with a mix of code behind and Xaml (I find data template selector cumbersome, where we could rely on Custom ContentViews to provide a rendering entry point.)
Assuming that we have :
Would it be possible to have on the main page :
and in the Page's ViewModel :
The idea would be that in absence of custom DataTemplate (which is very convenient for development), we'd rely on the ContentViews list only to derive the look of the CollectionView ?
I also tried ListView control, but it seems it works more or less the same way, regarding how data is displayed.
Beta Was this translation helpful? Give feedback.
All reactions