David Zomada
David Zomada

Reputation: 157

Button multi click issue Xamarin.Forms

On my Xamarin.Forms app I using a three different types of Buttons. These are their on click functionalities:

Navigation Buttons: I use them to navigate to an other page if I will need to came back later to the previous page.

btn_navigate.Clicked += (sender,e) => {
    Navigation.PushAsync(new Page());
};

Error: If the new page takes a few seconds to load, doing a quick multi click on these buttons open several pages.

Non returnable navigation Buttons: I use them to navigate to an other page when I want to avoid the user came back to the previous page. I destroy the current page after I insert before my new page.

btn_non_returnable_navigate.Clicked += (sender,e) => {
    Navigation.InsertPageBefore(new Page(), this);
    Navigation.PopAsync();
};

Error: If the new page takes a few seconds to load, doing a quick multi click on these buttons throws an exception: Before must be in the pushed stack of the current context. This is because the first click create the new page and destroy the current one, the second click cant not destroy to the current page because it is already destroyed so it throws the exception.

HTTP request Buttons: I use them to send a HTTP request to the server. Usually after the HTTP request was completed it navigate to an other page. Those are obviously the more important ones.

btn_http_request.Clicked += (sender,e) => {
    Uri uri = new Uri("http://192.168.0.1:8080/request");
    HttpClient client = new HttpClient();
    HttpResponseMessage http_response = client.GetAsync(uri);
    ....
    Navigation.InsertPageBefore(new Page(), this);
    Navigation.PopAsync();
};

Error: If the request takes a few seconds to get the answer, doing a quick multi click on these buttons throws several HTTP request. It should not happen.

All of these buttons are combined on the same page multiple times. So if the user try to click multiple buttons repeatedly he will tear down the app.

These issues are caused because the asynchronously of the button actions. But I think it will be solve by using a locker for these buttons so they could only clicked once a time.

Have Buttons some property like this? If it is not, how could I create a Buttons extension that fix this problems? I would like to have as simple solution as it possible. I need to control this issue in a lots of Buttons and if it is a complicated solutions it may do a tricky code problem.

On WPF this code works as I need but on Xamarin there is not RoutedEventArgs:

C# Button extension

public partial class ButtonEx : Button{
    public bool Active;
    public ButtonEx(){
        InitializeComponent();
        Active = true;
    }

    private void Extension_Click(object sender, RoutedEventArgs e){
        if (Active) {
            Active = false;
        } else {
            e.Handled = true;
        }
    }
}

XAML Button extension

<Button x:Class="test.ButtonEx"
  ..
  Click="Extension_Click">
</Button>

C# on the code

... 
ButtonEx buttonEx = new ButtonEx()
//Click function of the button
buttonEx.Click += (sender, e) =>{
    //This code only happen if buttonEx.active = true
    ... 
    (sender as Button).Active = true;
}
...

When you click the extended button it throws two events. The fist one, the Extension_Click and the second one the Click function of the button. The second event only happen when the buttonEx.active = true. The first even allows or blocks the second.

It is there an alternative like this to Xamarin.Formns?

Thank you

Upvotes: 0

Views: 577

Answers (1)

Ivan I
Ivan I

Reputation: 9990

The best practice for this including on WPF is to make the button disabled while it performs some action and shouldn't/can't perform additional actions. That is by the book. Technically someone can make a new sort of button that would perform this automatically. I would guess that the fact that no one made it by now is that this is not worth the effort / brings at least as much troubles as it resolves. Unfortunately I would guess that if you need something like that you will have to make it yourself, but it is definitely possible.

Upvotes: 1

Related Questions