Kamenskyh
Kamenskyh

Reputation: 495

ImageButtonGestureRecognizers for custom button

I have a collection view with my custom buttons.And have a function which change color of images and their background.My problem: it works with every button if I click,I want to make function which will change color and backgroundcolor of my SELECTED button.I thought maybe to make controls:CustomRoundButton.GestureRecognizers but I don`t understand how to write this function.Or maybe other function

            <CollectionView  ItemsSource="{Binding Cars}"      

                   SelectionMode="None">

                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical"
                Span="3" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="90" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="100" />
                                <ColumnDefinition Width="100" />
                                <ColumnDefinition Width="100" />
                            </Grid.ColumnDefinitions>
                            <Frame CornerRadius="10" BorderColor="Black" Margin="5,5,5,5" Padding="0"
                       >
                              <controls:CustomRoundButton TintColor="#616161" HeightRequest="90"
                             WidthRequest="90" CornerRadius="10" HorizontalOptions="Center"
                          BackgroundColor="White" ImageSource="heart" Clicked="Button_OnClicked"/>                             
                        </Frame>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

private void Button_OnClicked(object sender, EventArgs e)

{

    ((CustomRoundButton)sender).BackgroundColor = ((Button)sender).BackgroundColor == Color.White
        ? Color.FromHex("#2979FF")
        : Color.White;
    CustomRoundButton.SetTintColor((CustomRoundButton)sender, CustomRoundButton.GetTintColor((CustomRoundButton)sender) == Color.FromHex("#616161")
        ? Color.White
        : Color.FromHex("#616161"));

}

enter image description here

Upvotes: 2

Views: 65

Answers (1)

Leon Lu
Leon Lu

Reputation: 9274

I notice you used MVVM, you can achieve it my Command for your controls:CustomRoundButton .

Here is layout code.

 <StackLayout>
        <!-- Place new controls here -->
        <CollectionView  x:Name="BillView" ItemsSource="{Binding Cars}"      

                   SelectionMode="None">

            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical"
                Span="3" />
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="90" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="100" />
                        </Grid.ColumnDefinitions>
                        <Frame CornerRadius="10" BorderColor="Black" Margin="5,5,5,5" Padding="0" >
                            <controls:CustomRoundButton  HeightRequest="90"
                             WidthRequest="90" CornerRadius="10" HorizontalOptions="Center"
                          BackgroundColor="{Binding CustButtonColor}" ImageSource="{Binding Image}" Command="{ Binding BindingContext.ChangeCommand, Source={x:Reference Name=BillView} }"  CommandParameter="{Binding .}"/>
                        </Frame>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

Here is layout background code.

  public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = new MyModelView();
        }

       
    }

Here is code about MyModelView.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;

namespace CollectionViewDemo
{
     public class MyModelView
    {
        public ObservableCollection<Car> Cars { get; set; }
        public ICommand ChangeCommand { protected set; get; }
        public MyModelView()
        {
            Cars = new ObservableCollection<Car>();
            Cars.Add(new Car() { Image = "unheart.png",CustButtonColor=Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() { Image = "unheart.png", CustButtonColor = Color.Default });

            ChangeCommand = new Command<Car>((key) =>
            {
               
                var car = key as Car;
                if (car.Image == "heart.png")
                {
                    car.Image = "unheart.png"; car.CustButtonColor = Color.Default;
                }
                else
                {


                    car.Image = "heart.png";
                    car.CustButtonColor = Color.Red;
                }
               

            });
        }
    }
    public class Car: INotifyPropertyChanged
    {
        string image;
        public string Image
        {
            set
            {
                if (image != value)
                {
                    image = value;
                    OnPropertyChanged("Image");

                }
            }
            get
            {
                return image;
            }
        }

        Color _custButtonColor;
        public Color CustButtonColor
        {
            set
            {
                if (_custButtonColor != value)
                {
                    _custButtonColor = value;
                    OnPropertyChanged("CustButtonColor");

                }
            }
            get
            {
                return _custButtonColor;
            }
        }
      

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Here is running GIF.

enter image description here

======Update=======

but can you help me that only ONE selected button change background color and color of the icon on the image?

Do you want to achieve the result following GIF?

enter image description here

If so, please change the code of ChangeCommand.

  ChangeCommand = new Command<Car>((key) =>
            {
                foreach (var item in Cars)
                {
                    item.Image = "unheart.png";
                    item.CustButtonColor = Color.Default;
                }
                    var car = key as Car;
                    car.Image = "heart.png";
                    car.CustButtonColor = Color.Red;
            });

=======Update2=========

If you have different pictures, you can add a property called Name. we can reset ObservableCollection by name, when we click the Button.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;

namespace CollectionViewDemo
{
     public class MyModelView
    {
        public ObservableCollection<Car> Cars { get; set; }
        public ICommand ChangeCommand { protected set; get; }
        public MyModelView()
        {
            Cars = new ObservableCollection<Car>();
            Cars.Add(new Car() {Name="Audio", Image = "unheart.png",CustButtonColor=Color.Default });
            Cars.Add(new Car() {Name="BMW", Image = "faded_div.jpg", CustButtonColor = Color.Default });
            Cars.Add(new Car() {Name="BENZ", Image = "myIcon.png", CustButtonColor = Color.Default });
            Cars.Add(new Car() {Name="LEUX", Image = "wind.jpg", CustButtonColor = Color.Default });

           var DefaultCars= new ObservableCollection<Car>();
            DefaultCars = Cars;

            ChangeCommand = new Command<Car>((key) =>
            {
                //Rest the `ObservableCollection` by name.
                foreach (var item in Cars)
                {
                    if (item.Name.Equals("Audio"))
                    {
                        item.Image = "unheart.png";
                        item.CustButtonColor = Color.Default;
                    }else if (item.Name.Equals("BMW"))
                    {
                        item.Image = "faded_div.jpg";
                        item.CustButtonColor = Color.Default;
                    }
                    else if (item.Name.Equals("BENZ"))
                    {
                        item.Image = "myIcon.png";
                        item.CustButtonColor = Color.Default;
                    }
                    else if (item.Name.Equals("LEUX"))
                    {
                        item.Image = "wind.jpg";
                        item.CustButtonColor = Color.Default;
                    }
                   
                }
                var car = key as Car;
                


                    car.Image = "heart.png";
                    car.CustButtonColor = Color.Red;
              
               

            });
        }
    }
    public class Car: INotifyPropertyChanged
    {
        public string Name  { get; set; }
        string image;
        public string Image
        {
            set
            {
                if (image != value)
                {
                    image = value;
                    OnPropertyChanged("Image");

                }
            }
            get
            {
                return image;
            }
        }

        Color _custButtonColor;
        public Color CustButtonColor
        {
            set
            {
                if (_custButtonColor != value)
                {
                    _custButtonColor = value;
                    OnPropertyChanged("CustButtonColor");

                }
            }
            get
            {
                return _custButtonColor;
            }
        }
       

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Here is running GIF.

enter image description here

=========Update 3==============

You can set different icon for different button when you click it(set the different image by Name).

   ChangeCommand = new Command<Car>((key) =>
            {
                //reset the item to default image and background.
                foreach (var item in Cars)
                {
                    if (item.Name.Equals("Audio"))
                    {
                        item.Image = "unheart.png";
                        item.CustButtonColor = Color.Default;
                    }else if (item.Name.Equals("BMW"))
                    {
                        item.Image = "faded_div.jpg";
                        item.CustButtonColor = Color.Default;
                    }
                    else if (item.Name.Equals("BENZ"))
                    {
                        item.Image = "myIcon.png";
                        item.CustButtonColor = Color.Default;
                    }
                    else if (item.Name.Equals("LEUX"))
                    {
                        item.Image = "wind.jpg";
                        item.CustButtonColor = Color.Default;
                    }
                   
                }

                //set the different image by Name
                var car = key as Car;

                if (car.Name.Equals("BENZ"))
                {
                    car.Image = "sandwich.png";
                    
                }else if (car.Name.Equals("BMW"))
                {
                    car.Image = "rose.png";
                }
                else
                {
                    car.Image = "heart.png";

                }
                car.CustButtonColor = Color.Red;
              
               

            });
        }
    }

Here is running GIF.

enter image description here

Here is demo.

https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/CollectionViewDemo.zip

Upvotes: 2

Related Questions