0
votes

My project is in Xamarin.Forms, supported platform is iOS, android and Mac. I have two Stacklayout in single Xamrin.Forms.View and each Stacklayout has one button on same position. It means button 1 position is x=100 and y=100 in first Stacklayout and button 2 position in second Stacklayout is same as first Stacklayout. By default first Stacklayout Visible and second one is hide, now when I clicked on button 1 then first Stacklayout hide and visible second layout after API response arrived.

When user click on button 1 then I immediately change text to "Please Wait" and here button textcolor is set to White for better view in dark button background. Lets consider that API take 10 second time to do process, In between if user click multiple time on button 1 then in Mac platform, Mac will store/preserver those clicked events somewhere and when second Stacklayout Visible after 10 seconds, then mac immediately fire those stored/preserved clicked events for button 2 even user not clicked on button 2. How can I prevent it?

I have tried to set IsEnabled=false of button 1 once user clicked on it, it works fine in above scenario but when I do button to disabled in that case button text color changed from white to Black automatically in mac platform. I do not want to change color of text. If any one have solution to change color of text in disabled mode then it works for me OR if any other solution to prevent multiple click then please let me know.

1
Hi! If at the end you finally found a way to solve your problem please share it, or if the answer published below helped to achieve your goal, mark it as answer. By doing so you make this post useful for others having a similar issue. Thanks for contributing to the SO community!Deczaloth

1 Answers

0
votes

So, this is how i would go around this problem:

I would add a Label to the view, so we have button1, label, button2: one above each other.

At start you have button1 visible and the other two not visible.

When button1 is tapped, it is hidden: button1.IsVisible = false. Immediately label is set to visible and then, you can sit and wait until the operation finishes (it is crucial that you await it inside the button's event handler!!), and when the job is done, you set label visibility to false, and button2 as visible.

And you can go back again following the same logic.

The final result is that when you tap on button1, the label appears instead, so if the user keeps on tapping, those taps are not stored/preserved!


A code for Xamarin.Forms that would do exactly that would be as follows.

XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Page1">
    <ContentPage.Content>
        <Grid HorizontalOptions="CenterAndExpand" 
              VerticalOptions="CenterAndExpand">

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Button x:Name="button1" 
                    Text="Go to the Moon!"
                    Clicked="Button_Clicked"/>

            <Label x:Name="label" 
                   IsVisible="False"/>

            <Button x:Name="button2"
                    Text="Go back home!"
                    IsVisible="False"
                    Clicked="Button_Clicked_1"/>

        </Grid>
    </ContentPage.Content>
</ContentPage>

Code behind

using System;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Page1 : ContentPage
    {
        public Page1 ()
        {
            InitializeComponent ();
        }

        String text1 = "Going to the moon...";

        String text2 = "Going back home...";


        private async void Button_Clicked(object sender, EventArgs e)
        {

            ((Button)sender).IsVisible = false;

            label.Text = text1;
            label.IsVisible = true;

            // Simulates running process!
            await Task.Delay(3000);

            label.IsVisible = false;
            button2.IsVisible = true;

        }

        private async void Button_Clicked_1(object sender, EventArgs e)
        {
            ((Button)sender).IsVisible = false;

            label.Text = text2;
            label.IsVisible = true;

            // Simulates running process!
            await Task.Delay(3000);

            label.IsVisible = false;
            button1.IsVisible = true;

        }
    }
} 

I hope you find this useful :)