Jay.Smyth
Jay.Smyth

Reputation: 77

Xamarin toggle a group of image buttons but each image button has their own method

I have a group of image buttons, each button has its own click event, I want to toggle the size of each button on a click event then reset when another button is pressed. I'm really new to c# and Xamarin, but I have found a really ugly way of doing it, this is a question of how to do it better.

xaml

<ImageButton Source="test.png"
             x:Name="btn-1"
             Clicked="btn-1_Clicked"/>
<ImageButton Source="test.png"
             x:Name="btn-2"
             Clicked="btn-2_Clicked"/>
<ImageButton Source="test.png"
             x:Name="btn-3"
             Clicked="btn-3_Clicked"/>
<ImageButton Source="test.png"
             x:Name="btn-4"
             Clicked="btn-4_Clicked"/>

xaml.cs

public string isClicked;

private void btn-1_Clicked(object sender, EventArgs e)
    {
        isClicked = "Yes btn 1";
        isBtnClicked();
    }
private void btn-2_Clicked(object sender, EventArgs e)
    {
        isClicked = "Yes btn 2";
        isBtnClicked();
    }
private void btn-3_Clicked(object sender, EventArgs e)
    {
        isClicked = "Yes btn 3";
        isBtnClicked();
    }
private void btn-4_Clicked(object sender, EventArgs e)
    {
        isClicked = "Yes btn 4";
        isBtnClicked();
    }

Ok here comes the horrible part, now the reason for this is that the variable that the button sets is used elsewhere, but the images I use are essentially icons and I've hid the button part of the UI behind the image

public void isBtnClicked(){
if (isClicked == "Yes btn 1")
        {
            btn-1.ScaleTo(0.8);
            btn-2.ScaleTo(1);
            btn-3.ScaleTo(1);
            btn-4.ScaleTo(1);
        } else if (Emotion == "Yes btn 2")
        {
            btn-1.ScaleTo(1);
            btn-2.ScaleTo(0.8);
            btn-3.ScaleTo(1);
            btn-4.ScaleTo(1);
        } else if (Emotion == "Yes btn 3")
        {
            btn-1.ScaleTo(1);
            btn-2.ScaleTo(1);
            btn-3.ScaleTo(0.8);
            btn-4.ScaleTo(1);
        } else
        {
            btn-1.ScaleTo(1);
            btn-2.ScaleTo(1);
            btn-3.ScaleTo(1);
            btn-4.ScaleTo(0.8);
        }
}

I'm sure I'm running into loads of bad practice and redundant code but as a complete novice would like feedback or solutions

Upvotes: 0

Views: 430

Answers (2)

Cherry Bu - MSFT
Cherry Bu - MSFT

Reputation: 10346

According to your description, you don't need to create many Button_click, I do some code according to bhavya's reply, don't use binding command, please take a look,

<StackLayout>
        <ImageButton
            x:Name="btn1"
            Clicked="button_click"
            Source="plu3.png" />
        <ImageButton
            x:Name="btn2"
            Clicked="button_click"
            Source="plu3.png" />
        <ImageButton
            x:Name="btn3"
            Clicked="button_click"
            Source="plu3.png" />
        <ImageButton
            x:Name="btn4"
            Clicked="button_click"
            Source="plu3.png" />
    </StackLayout>



 private void resetallbuttons()
    {
        btn1.ScaleTo(1);
        btn2.ScaleTo(1);
        btn3.ScaleTo(1);
        btn4.ScaleTo(1);
    }
    private void button_click(object sender, EventArgs e)
    {
        resetallbuttons();
        //this is the button that you click
        ImageButton btn = (ImageButton)sender;
        btn.ScaleTo(0.8);
    }

Upvotes: 1

bhavya joshi
bhavya joshi

Reputation: 1136

First of all, never use - for defining variables.It's not a good pratice.Better to use _.

Now to make your bonding strong with Xamarin you should use CommandParameter. If you don't know much about CommandParameter then go through this: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/commanding. Trust me,this is an essential part of xamarin and should know about it if you are serious about Xamarin.

Use ImageButton as:

    <ImageButton Source="test.png" x:Name="btn1"
                 Command="{Binding Btn_ClickedCommand}"
                 CommandParameter="{x:Reference btn1}"/>
    <ImageButton Source="test.png" x:Name="btn2"
                 Command="{Binding Btn_ClickedCommand}"
                 CommandParameter="{x:Reference btn2}"/>
    <ImageButton Source="test.png" x:Name="btn3"
                 Command="{Binding Btn_ClickedCommand}"
                 CommandParameter="{x:Reference btn3}"/>
    <ImageButton Source="test.png" x:Name="btn4"
                 Command="{Binding Btn_ClickedCommand}"
                 CommandParameter="{x:Reference btn4}"/>

Create a ViewModel page namely 'TestViewModel.cs' and bind you current page to this view model through BindingContext=new TestViewModel();. It's always a good idea to use ViewModel for this kind of functionalities.

Now in TestViewModel.cs define commands:

public ICommand Btn_ClickedCommand{get;set;}

and in Constructor:

Btn_ClickedCommand = new Command<object>(isBtnClicked);

create a method isBtnClicked(you have already created)

    public void isBtnClicked(object sender){
       ResetAllButtons(); //First reset all buttons.
       if(sender is ImageButton imageButton){
          imageButton.ScaleTo(0.8); //then scale that particular button
       }
    }

    public void ResetAllButtons(){
        btn1.ScaleTo(1);
        btn2.ScaleTo(1);
        btn3.ScaleTo(1);
        btn4.ScaleTo(1);
    }

Upvotes: 1

Related Questions