Home > front end >  How to send a parameter in click event in xamarin
How to send a parameter in click event in xamarin

Time:03-30

I am quite new to Xamarin. I want to send my Binding id as a parameter of click event of button.

So here is my button:

<Button
    Text="{Binding Name}"
    Grid.Column="0"
    HorizontalOptions="Center"
    VerticalOptions="Center"
    TextColor="Black"
    BackgroundColor="#EEF2FF"
    Command="{Binding Handle_AddProduct}"
                                    CommandParameter="{Binding id}"
/>

So I want to send a {Binding id} as a parameter with addProducts.

Here id my controller:

public ObservableCollection<Product> AllProducts { get => GetProduct(); }

        private ObservableCollection<Product> GetProduct()
        {
            return new ObservableCollection<Product>
            {
                new Product { id=1, Type = "Drink", Name = "Cola", Stock = 123 },
            };
        }
        private ObservableCollection<addedProduct> _addedProduct;
        public ObservableCollection<addedProduct> addedProducts
        {
            get
            {
                return _addedProduct ?? (_addedProduct = new ObservableCollection<addedProduct>());
            }
        }
        protected void Handle_AddProduct(addedProduct newproduct)
        {
            foreach (var product in AllProducts)
            {
                if (newproduct.id == product.id)
                {
                    addedProducts.Add(newproduct);
                }
            }
        }
        public ICommand addProducts { private set; get; }

public class Product
    {
        public int id { get; set; }
        public string Type { get; set; }
        public string Name { get; set; }
        public int Stock { get; set; }
    }
    public class addedProduct
    {
        public int id { get; set; }
        public string Type { get; set; }
        public string Name { get; set; }
        public int Stock { get; set; }
    }

In general what I am trying to do is when the button is clicked, the object (given as a parameter) should be added to my addedProduct list and later I can show it in another view. Fr example one of the button is Cola, so when it is clicked I am sending id as a parameter and it is searching the Product list and if it find Cola inside of that list I am sending it to addedProduct list.

I hope I am clear. Thanks for the help.

CodePudding user response:

Try using a Command instead of the button Clicked event. If you use the Command you can add a custom parameter via the CommandParameter property.

Check out the documentation for Commands here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/commanding#using-command-parameters

The result might look like this:

<Button
    Text="{Binding Name}"
    Grid.Column="0"
    HorizontalOptions="Center"
    VerticalOptions="Center"
    TextColor="Black"
    BackgroundColor="#EEF2FF"
    Command="{Binding AddProductCommand}"
    CommandParameter="{Binding .}"
/>
public class MyViewModel{
    public ObservableCollection<Product> AllProducts { get; } = new ObservableCollection<Product>();

    public ObservableCollection<Product> AddedProducts { get; } = new ObservableCollection<Product>();

    public ICommand AddProductCommand { get; }

    public MyViewModel(){
        AddProductCommand = new Command<Product>(AddProduct);

        AllProducts.Add(new Product { id = 1, Type = "Drink", Name = "Cola", Stock = 123 });
    }

    private void AddProduct(Product newProduct)
    {
        AddedProducts.Add(newProduct);
    }
}

CodePudding user response:

Is your Button in your DataTemplate of your listview?

If yes, then you have to change your command as follows:

                    <Button  Text="add"  Grid.Column="0"
                             HorizontalOptions="Center"
                             VerticalOptions="Center"
                             TextColor="Black"
                             BackgroundColor="#EEF2FF"
                             Command="{Binding Path=BindingContext.AddProductCommand, Source={x:Reference lstView}}"  
                             CommandParameter="{Binding .}"

Note: lstView is the x:Name="lstView" of your outer View(e.g. ListView).

You can refer to the following code:

<ContentPage.BindingContext>
    <sendparmdemo:MyViewModel></sendparmdemo:MyViewModel>
</ContentPage.BindingContext>

<ListView  x:Name="lstView" RowHeight="60" Grid.Row="1"  ItemsSource="{ Binding AllProducts}" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid ColumnSpacing="3" HorizontalOptions="FillAndExpand">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <BoxView Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>
                    <BoxView Grid.Column="1" Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>
                    <BoxView Grid.Column="2" Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>

                    <Button  Text="add"  Grid.Column="0"
                             HorizontalOptions="Center"
                             VerticalOptions="Center"
                             TextColor="Black"
                             BackgroundColor="#EEF2FF"
                             Command="{Binding Path=BindingContext.AddProductCommand, Source={x:Reference lstView}}"  
                             CommandParameter="{Binding .}"
                     />
                    <Label Text="{Binding Type}" HorizontalOptions="Fill" Grid.Column="1" HorizontalTextAlignment="Left" VerticalTextAlignment="Center"/>
                    <Label Text="{Binding Name}" HorizontalOptions="Fill" Grid.Column="2" HorizontalTextAlignment="Left" VerticalTextAlignment="Center"/>
                    <Label Text="{Binding Stock}" HorizontalOptions="Fill" Grid.Column="3" HorizontalTextAlignment="Left" VerticalTextAlignment="Center"/>
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

MyViewModel.cs

public class MyViewModel
{
    public ObservableCollection<Product> AllProducts { get; set; } = new ObservableCollection<Product>();
    public ObservableCollection<Product> AddedProducts { get; } = new ObservableCollection<Product>();

    public ICommand AddProductCommand { get; }

    private ObservableCollection<Product> GetProduct()
    {
        return new ObservableCollection<Product>
        {
           new Product { id=1, Type = "Drink", Name = "Cola", Stock = 123 },

           new Product { id=2, Type = "Drink", Name = "Water", Stock = 123 },

           new Product { id=3, Type = "Drink", Name = "Soda", Stock = 123 }
        };
    }

    public void AddProduct(Object newProduct)
    {
        Product product = newProduct as Product;

        System.Diagnostics.Debug.WriteLine("----> add product  id = "   product.id  "<---->  Name = "   product.Name);

        AddedProducts.Add(product);
    }
    public MyViewModel() {
         AddProductCommand = new Command(AddProduct);

        AllProducts = GetProduct();
    }
}

Note:

1.I used a Listview to simulate your functionality, you can change it to your view.

2.And since you have a Label to display Name property, I changed button's text to Add, which makes the functionality clearer.

  • Related