David Shochet
David Shochet

Reputation: 5395

How can I intercept opening a picker in .Net MAUI?

I have a .Net MAUI app with CommunityToolkit.Mvvm.

Here is my picker:

                    <Picker Title="Choose Trowel Size..."
                        ItemsSource="{Binding TrowelCoveragesByUnit}"
                        ItemDisplayBinding="{Binding ThicknessText}"
                        SelectedItem="{Binding SelectedTrowelSize}"
                        Style="{StaticResource PickerStyle}"
                        Grid.Row="3" Grid.Column="1" />

This is in my page model:

    public List<TrowelCoverageByUnit> TrowelCoveragesByUnit =>
        TrowelCoverages.Select(tc => SelectedUnit.Code == "sqft" ?
        new TrowelCoverageByUnit(tc.ThicknessTextInches, tc.ThicknessValueInches, tc.Coverage) :
        new TrowelCoverageByUnit(tc.ThicknessTextMetric, tc.ThicknessValueMetric, tc.Coverage)).ToList();

    [ObservableProperty]
    [NotifyPropertyChangedFor(nameof(TrowelCoveragesByUnit))]
    [Required(ErrorMessage = "Unit of measure is required!")]
    private Unit _selectedUnit;

As we can see, if SelectedUnit property is null, TrowelCoveragesByUnit list is empty, and thus the picker is also empty. I need to avoid showing an empty list in the picker. Instead, if SelectedUnit is empty, I don't want the picker to open upon tap, rather, I need to display

Shell.Current.DisplayAlert("Unit of Measure Required", "Please select unit of measure first.", "OK");

Is it possible to do it, and if so, how?

Upvotes: 0

Views: 70

Answers (1)

David Shochet
David Shochet

Reputation: 5395

According to Jason's suggestion, I added a transparent BoxView

                <Label Text="Trowel Size (WxH):" Style="{StaticResource LabelEntryStyle}" Grid.Row="3" Grid.Column="0" />
                <Picker x:Name="TrowelSizePicker"
                        Title="Choose Trowel Size..."
                        ItemsSource="{Binding TrowelCoveragesByUnit}"
                        ItemDisplayBinding="{Binding ThicknessText}"
                        SelectedItem="{Binding SelectedTrowelSize}"
                        Style="{StaticResource PickerStyle}"
                        Grid.Row="3" Grid.Column="1" />

                <BoxView Grid.Row="3" Grid.Column="1"
                    Color="Transparent">
                    <BoxView.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnPickerTapped" />
                    </BoxView.GestureRecognizers>
                </BoxView>

And we handle the tap gesture in code behind:

private async void OnPickerTapped(object sender, EventArgs e)
{
    var viewModel = BindingContext as EstimatorAdhesiveInputPageModel;
    if (viewModel != null && viewModel.SelectedUnit == null)
    {
        await Shell.Current.DisplayAlert("Unit of Measure Required", "Please select unit of measure first.", "OK");
    }
    else
    {
        // Focus the picker to open it
        TrowelSizePicker.Focus();
    }
}

IMPORTANT: Make sure to use Color="Transparent" and not BackgroundColor="Transparent", which would give always black background.

This works as expected. Though I would prefer using a command in the view model, but not sure it is possible with this approach.

Upvotes: 0

Related Questions