ImageButton Command behaves different from Button Comman when navigating to a map view in .Net MAUI

200 Views Asked by At

I am building a simple app using .Net Maui with MVVM architecture . The app shows maps in some views and i used the "Microsoft.Maui.Controls.Maps NuGet package" for interacting with google maps following the official docs "maps official docs". i used CommunityToolkit.Maui and CommunityToolkit.Mvvm to help with the mvvm architectrue.

every thing worked fine until i had a simple problem that i kept debugging and trying to resolve for a while and reached nothing. and it was really frustrating because i replicated the code in the same application and it worked fine while the code is almost identical , long story short after a weak i discovered that the problem happens when i use an image button instead of a regular button to navigate to the map view when clicked.

so to replicate the problem i built a simple app where i have a view with only a button and an ImageButton that's when each one is clicked it will navigate to the view with the map , the map will have a map span that should specify the visible region initially in the map

if i clicked the button the map span works fine , if i clicked the ImageButton the map shows and works fine but it is as if there was no map span specified .

this is the repo i used to abstract and replicate the problem "reproduction code repo"

these details are in the readme of the repo but i will put it again

  • first you have to aquire an api key for google maps as described in the docs "maps official docs" and put it in platforms/android/androidmanifest.xml file replace 'the Enter Your APIKEY Here' with your aquired api key
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
        <meta-data android:name="com.google.android.geo.API_KEY" android:value="ENTER_YOUR_API_KEY_HERE" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

we have 2 views view with the 2 buttons and a view that shows the map

<VerticalStackLayout>
        <Button Text="MAP" ImageSource="marker.png" Command="{Binding ButtonCommand}" Margin="100"/>

        <ImageButton Source="marker.png" Command="{Binding ImageButtonCommand}"/>
    </VerticalStackLayout>

i used 2 different commands for both buttons because if i used the same command for both buttons, then when clicking one button it acts like i clicked both the buttons *i know from the click animation on both * and then the problem will not arise , however if the button is made invisible the problem will arise again. this is another weird thing that happens

this is the view model of the buttons view

private readonly INavigationService _navigationService;

        public ICommand ButtonCommand { get; }
        public ICommand ImageButtonCommand { get; }
        public ButtonsViewModel(INavigationService navigationService) 
        {
            _navigationService = navigationService;

            ButtonCommand = new AsyncRelayCommand(ButtonGoToMap);
            ImageButtonCommand = new AsyncRelayCommand(ImageButtonGoToMap);
        }

        private async Task ButtonGoToMap()
        {
            await _navigationService.NavigateToAsync("//map");
        }

        private async Task ImageButtonGoToMap()
        {
            await _navigationService.NavigateToAsync("//map");
        }

the

NavigateToAsync

method simply navigates to the map

public Task NavigateToAsync(string route, IDictionary<string, object> routeParameters = null)
        {
            var shellNavigation = new ShellNavigationState(route);

            return routeParameters != null
                ? Shell.Current.GoToAsync(shellNavigation, routeParameters)
                : Shell.Current.GoToAsync(shellNavigation);
        }

registration of routes , views , viewmodels, services are all done correctly

buttons view

<maps:Map>
        <x:Arguments>
            <MapSpan>
                <x:Arguments>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>36.9628066</x:Double>
                            <x:Double>-122.0194722</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    <x:Double>0.01</x:Double>
                    <x:Double>0.01</x:Double>
                </x:Arguments>
            </MapSpan>
        </x:Arguments>
    </maps:Map>

when clicking the button the map shows the correct region specified by the map span

correct map

but when clicking the image button the map act like there is no map span

wrong map

additional info that might help , when using the imagebutton case ,if i have multiple pages when the problem happens if i navigated to another page and then navigated back to the map view directly it will display the correct region

i know this problem is easy to work around by using a button with image source instead of the imagebutton , but i want to know if i am doing any thing wrong or am i missing some thing or misunderstanding any thing , this might help me later on .

or is it just a problem with the image button or a problem with the map i dont know .

it will be great if someone could help .

--> FOLLOW UP

i tried a different approach to use the MoveToRegion method on the map directly as follows the map view

<maps:Map x:Name="MyMap">
    </maps:Map>

the code behind

public MapView(MapViewModel mapViewModel)
{
    BindingContext= mapViewModel;
    InitializeComponent();
    mapViewModel.MyMap = MyMap;
    mapViewModel.GoToRegion();
}

the viewmodel

private Map _map;
    public Map MyMap
    {
        get => _map;
        set => SetProperty(ref _map, value);
    }
    public MapViewModel() {
        _map = new Map();
    }

    public void GoToRegion()
    {
        Location location = new Location(36.9628066, -122.0194722);
        MapSpan mapSpan = new MapSpan(location, 0.01, 0.01);
        _map.MoveToRegion(mapSpan);
    }

it still works with the button and doesn't work with the image button

0

There are 0 best solutions below