maui

Selecting ContentView based on condition in .NET MAUI


In my .NET MAUI app, I have to display a button or a label depending on the value of some data.

I have a ContentView that displays data in a Grid and this is where I need to figure out a way to display the button or the label. I've used selectors before but it was always in a CollectionView.

Is there a way to use a selector in a Grid?

<ContentView
   xmlns:model="MyApp.Models"
   x:DataType="model:MyModel">
    
   <Grid
      RowDefinitions="75,75,75,*">
    
      <Label
         Grid.Row="0"
         Text="{Binding Property1}" />
    
      <Label
         Grid.Row="1"
         Text="{Binding Property2}" />
    
      <!-- This is where I need to either render the button or a label -->
    
   </Grid>
    
</ContentView>

Separately, I have two ContentView's i.e. MyButtonView and StatusView that I will use depending on the data. Just not sure how to handle the decision making process. I was thinking using a selector may work nicely here.


Solution

  • Since you're just dealing with a bool, you can simply control the visibility of the Button and the Label using their IsVisible property in combination with your bool and the InvertedBoolConverter from the MAUI Community Toolkit (MCT):

    <ContentView
       xmlns:model="MyApp.Models"
       xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
       x:DataType="model:MyModel">
    
       <ContentView.Resources>
           <mct:InvertedBoolConverter x:Key="BooleanConverter" />
       </ContentView.Resources>
    
       <Grid
          RowDefinitions="75,75,75,*">
    
          <Label
             Grid.Row="0"
             Text="{Binding Property1}" />
    
          <Label
             Grid.Row="1"
             Text="{Binding Property2}" />
    
          <!-- This is where I need to either render the button or a label -->
    
          <!-- Show StatusView when value is true, hide it if false -->
          <StatusView
             Grid.Row="2"
             IsVisible="{Binding YourBool}" />
    
          <!-- Show MyButtonView when value is false, hide it if true -->
          <MyButtonView
             Grid.Row="2"
             IsVisible="{Binding YourBool, Converter={StaticResource BooleanConverter}}" />
    
       </Grid>
    
    </ContentView>
    

    If you don't want to use the MCT, you can also implement the InvertedBoolConverter yourself:

    using System.Globalization;
    
    namespace MyApp.Converters;
    
    public class InvertedBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Binding.DoNothing;
        }
    }
    

    I know that you find this solution "kludgy", but this is quite a common way of doing it in simple scenarios. It's less complex than using data templates and a template selector and I usually recommend taking the easiest path.