Home > Mobile >  Xamarin: ImageButton not invoking command from style setter
Xamarin: ImageButton not invoking command from style setter

Time:06-03

I am trying to create a custom navigation/"back" button in my mobile app. I want to bind the command as a setter property in a custom style and then apply that style to the ImageButton element in a larger custom element called HeaderNavigation.

Everything builds so that I can see my ImageButton with its styles applied. I can also see the command applied to the ImageButton when I watch its styles but, if I click on the ImageButton, the command is not called.

I've played around with the binding a little bit because I'm assuming that's the issue but no dice yet so I'm worried what I'm attempting isn't possible or maybe there's something stupid I'm missing.

Even if someone could just give me some debugging tips for mobile bindings, that would be helpful.

Thanks!

Code below:

app.xaml

<Style x:Key="NavButton" TargetType="ImageButton" BasedOn="{StaticResource IconButton}">
        <Setter Property="Source" Value="back.png"/>
        <Setter Property="HorizontalOptions" Value="EndAndExpand"/>
        <Setter Property="Command" Value="{Binding Source={RelativeSource AncestorType={x:Type local:App}},Path=BindingContext.OnBackButtonPressed}"/>
        <Setter Property="BackgroundColor" Value="{StaticResource Background}"/>
</Style>

App.xaml.cs

public async void OnBackButtonPressed(object sender, EventArgs e)
{
        // I do not get called :(
        _ = await Navigation.PopAsync();
}

HeaderNavigation.cs

public class HeaderNavigation : StackLayout
{
    private ImageButton _returnButton;

        public HeaderNavigation()
        {
            _returnButton = new ImageButton();

            _returnButton.Style = (Style)Application.Current.Resources["NavButton"];

            Children.Add(_returnButton);
        }
    }
}

CodePudding user response:

Two problems:

  1. That method isn't a command. Property Command needs to be bound to a Command. in App.xaml.cs:
public Command BackButtonCommand { get; } = new Command(BackButtonAction);

private void BackButtonAction()
{
    ...
}
  1. App does not have a BindingContext. Refer to a command on the App object itself. Change xaml value to:
... Value="{Binding Source={RelativeSource AncestorType={x:Type local:App}}, Path=BackButtonCommand}" ...

NOTE: Not tested.

CodePudding user response:

My understanding is that your goal is to have the back button call the OnBackButtonPressed method in your App class:

public partial class App : Application
{
    public async void OnBackButtonPressed(object sender, EventArgs e)
    {
        // This pop up will be the test.
        await MainPage.DisplayAlert("Message from button", "It worked", "OK");
    }
}

Chances are your custom NavigationHeader is going to be consumed in a view of some kind (e.g. ContentPage). I'm seeing an answer with a nice direct approach and would say if that works use it:) As a backup, here is a different strategy that I've tested enter image description here

  • Related