Search code examples
xamlmauiconvertersmaui-community-toolkit

Why Does the "IsVisible" Property not Work with the "IsListNullOrEmptyConverter" After Emptying an ObservableCollection?


I've included an "attach images" button in a .NET MAUI application which works just fine. Right next to that, I've included an delete button and a picker depicting the file names of the images previously picked:

 <!-- Attach Image Button -->
 <Button MaximumWidthRequest="150"
         Text="Attach images"
         TextColor="{StaticResource SnowWhite}"
         BackgroundColor="{StaticResource AlpineBlue}"
         CornerRadius="25"
         Command="{Binding AttachImagesCommand}">
     <Button.ImageSource>
         <FontImageSource FontFamily="MSO"
                          Glyph="{x:Static helpers:IconFont.Attach_file_add}"
                          Size="20"
                          Color="{StaticResource NightBlue}" />
     </Button.ImageSource>
 </Button>

 <!-- Delete Attached Image Button -->
 <Button BackgroundColor="{StaticResource SnowWhite}"
         Command="{Binding RemoveImageCommand}"
         IsVisible="{Binding Images, Converter={StaticResource IsListNotNullOrEmptyConverter}}">
     <Button.ImageSource>
         <FontImageSource FontFamily="MSO"
                          Glyph="{x:Static helpers:IconFont.Delete}"
                          Size="20"
                          Color="{StaticResource NightBlue}" />
     </Button.ImageSource>
 </Button>

 <!-- Images Picker -->
 <Picker
     ItemsSource="{Binding Images}"
     ItemDisplayBinding="{Binding FileName}"
     SelectedItem="{Binding CurrentImage, Mode=TwoWay}"
     SelectedIndex="{Binding CurrentImageIndex, Mode=TwoWay}"
     IsVisible="{Binding Images, Converter={StaticResource IsListNotNullOrEmptyConverter}}"
     />

enter image description here

The delete button also seem to work fine, since it's removing the FileResult in the ViewModel from the ObservableCollection attached to that:

[ObservableProperty]
private FileResult _currentImage = null;

[ObservableProperty]
private int _currentImageIndex = 0;

[ObservableProperty]
private ObservableCollection<FileResult> _images = new();

// ...

[RelayCommand]
private async Task OnAttachImagesAsync()
{
    var results = await FilePicker.PickMultipleAsync(new PickOptions
    {
        PickerTitle = "Pick Image(s) Please",
        FileTypes = FilePickerFileType.Images
    });

    if (results == null)
        return;

    Images = new ObservableCollection<FileResult>(results);
    CurrentImage = Images.First();
}

// ...

[RelayCommand]
private void OnRemoveImage()
{
    Images.RemoveAt(CurrentImageIndex);
}

However, if all items in the ObservableCollection have been removed, the two components are still visible:

enter image description here

Why is the Converter "IsListNullOrEmptyConverter" of the .NET MAUI Community Toolkit working fine at the beginning of the view but does not update accordingly? Do I miss a directive, like Mode=TwoWay in the XAML or NotifyCanExecuteChanged in C#?


Solution

  • as Julian suggests, you need to manually call OnPropertyChanged() when you remove the last item:

    [RelayCommand]
    private void OnRemoveImage()
    {
        Images.RemoveAt(CurrentImageIndex);
    
        if (Images.Count == 0)
            OnPropertyChanged(nameof(Images));
    }