Search code examples
mauiuicollectionviewcellcollectionview

.NET Maui CollectionView, how to display value only if value exists


I would like to display the properties in a list of objects, but if the properties don't have any values I'd like to not only leave it blank but have the entire row not there at all (that's key).

Here's what I mean: let's say I have an object with four string values:

object person:
string firstname
string lastname
string favoriteMovie
string favoriteBook

Actually, I have a list of them: ObservableList<Person>. I want to display Person and the properties in each Person using CollectionView, only if the property doesn't have a value I want to skip it.

It might looks something like this:
enter image description here

The XAML code would look something like this:

<CollectionView ItemsSource={Binding People}>
   <CollectionView.ItemTemplate>
      <DataTemplate x:DataType="model:Person">
           <Frame>
               <Grid>
                   <Label Text="{Binding Name}"/>
                   <Label Text="{Binding FavoriteMovie}"/>
                   <Label Text="{Binding FavoriteBook}"/>
               ...
            ...
        ...
      ...
  </CollectionView>

How do I do that?

NOTE: I'm using MVVM pattern, and I'd like to mostly do this in XAML if possible.


Solution

  • You will need a Converter that converts empty or null strings to booleans and then you need to assign it to the visibility of your item so something like the below would work,

    /// <summary>
    /// Inherit this for one-way converters to avoid unnecessary extra methods in each converter
    /// </summary>
    public abstract class BaseOneWayValueConverter : IValueConverter
    {
        public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException($"{GetType().Name} is a one-way converter");
        }
    }
    
    public class StringIsNullToBoolConverter : BaseOneWayValueConverter
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value is not string text || !string.IsNullOrWhiteSpace(text);
        }
    }
    

    And then use it in your Label as shown below:

    <ContentPage
    .
    .
    .
    .
    xmlns:converters=*converter-namepsace-here* 
    >
    <ContentPage.Resources>
       <StringIsNullToBoolConverter x:Key="StringIsNullToBoolConverter"/>
    </ContentPage.Resources>
    

    Then use it in your respective labels:

    <Label Text="{Binding Name}" IsVisible="{Binding Name,Converter={StaticResource StringIsNullToBoolConverter}}"/>