How to fire a Button command on SfListView

I have a SfListView that contain some text, images and three buttons. All fields are defined in the

DataTemplate. I want to fire a command when clicking a button and grabbing a value from a Bound variable on CommandParameter. I need help on figuring out how to achieve this using C#.

This is the definition from my button but the Command on my viewModel is not firing.


var bookmarkItButton = new SfButton()                {

                   BackgroundImage = new FileImageSource

                   {

                        File = "favoriteicon64.png"

                    },

                   CommandParameter = new Binding("id"),

                };

  

bookmarkItButton.SetBinding(SfButton.CommandProperty, new Binding("DigitCommand"));


on my view model I defined the command


                var DigitCommand = new Command<string>(

                execute: (string arg) =>

                {                  

System.Diagnostics.Debug.WriteLine("DigitCommand Key " + arg + " pressed");

                });


 

Thanks


5 Replies

LN Lakshmi Natarajan Syncfusion Team February 10, 2022 11:32 AM UTC

Hi Gabriel, 
 
You can bind the command and CommandParamater for button in code behind using SetBinding method. Please refer the following code snippets to bind command in code behind.  
 
var bookmarkItButton = new SfButton() 
{ 
    BackgroundImage = new FileImageSource 
    { 
        File = "bookmark.png" 
    }, 
 
    HeightRequest = 30, 
    WidthRequest = 30, 
    HorizontalOptions = LayoutOptions.End 
}; 
 
bookmarkItButton.SetBinding(SfButton.CommandProperty, new Binding() { Source = ListView.BindingContext, Path = "DigitCommand" }); 
 
bookmarkItButton.SetBinding(SfButton.CommandParameterProperty, new Binding() { Source = bookmarkItButton.BindingContext, Path = "ContactName" }); 
 
We have attached the tested sample in the following link, 
 
You can also refer to our user guidance document to bind command in SfListView.ItemTemplate from the following link, 
 
Please let us know if you need further assistance. 
 
Lakshmi Natarajan 
 



GA Gabriel February 10, 2022 12:28 PM UTC

hello and thanks  for the example. I ran the example and it work on Android  but it does not work on IOS. The button on IOS will not fire the command. I am not sure if there is anything missing.  Thanks



LN Lakshmi Natarajan Syncfusion Team February 11, 2022 05:23 AM UTC

Hi Gabriel, 
 
Please initialize the SfButtonRenderer.Init in the AppDelegate.cs class of the iOS project. Please refer to the following code snippets for more reference, 
 
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 
{ 
    // 
    // This method is invoked when the application has loaded and is ready to run. In this  
    // method you should instantiate the window, load the UI into it and then make the window 
    // visible. 
    // 
    // You have 17 seconds to return from this method, or iOS will terminate your application. 
    // 
    public override bool FinishedLaunching(UIApplication app, NSDictionary options) 
    { 
        global::Xamarin.Forms.Forms.Init(); 
                        SfListViewRenderer.Init(); 
        Syncfusion.XForms.iOS.Buttons.SfButtonRenderer.Init(); 
        LoadApplication(new App()); 
 
        return base.FinishedLaunching(app, options); 
    } 
} 
 
You can also refer to our user guidance document regarding the same, 
 
Please let us know if you need further assistance. 
 
Lakshmi Natarajan 
 



GA Gabriel February 12, 2022 01:43 PM UTC

Thanks for the example, I was able to run it successfully for a simple binding. but I am trying to bind two objects to the CommandProperty but in this case the command is not firing. I have the following definition:


StackLayout buyItStack = new StackLayout()

                {

                    BackgroundColor = Color.White,

                    HeightRequest = 50,

                    Orientation = StackOrientation.Vertical,

                    HorizontalOptions = LayoutOptions.CenterAndExpand,

                    VerticalOptions = LayoutOptions.CenterAndExpand

                };


                var buyItStackTapping = new TapGestureRecognizer();

                buyItStack.GestureRecognizers.Add(buyItStackTapping);

                buyItStackTapping.SetBinding(TapGestureRecognizer.CommandProperty, new Binding() { Source = ListView.BindingContext, Path = "BuyDigitCommand" });


                buyItStackTapping.SetBinding(TapGestureRecognizer.CommandParameterProperty, new MultiBinding

                {

                    Bindings = new Collection<BindingBase>

                    {

                        new Binding() { Source = buyItStackTapping.BindingContext, Path = "companyId" },

                        new Binding() { Source = buyItStackTapping.BindingContext, Path = "tourId" }

                    },

                    Converter = new DigitCommandConverter()

                });



The Converter is the following since I just want to receive the String coming from both  bindings:


public class DigitCommandConverter : IMultiValueConverter

    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)

        {

            return values;

        }



        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)

        {

            throw new NotImplementedException();

        }

    }



The view Model has the following:


public Command<string> BuyDigitCommand { get; set; }


public TourViewModel()

        {

            BuyDigitCommand = new Command<string>(OnBuyButtonClicked);

        }


private async void OnBuyButtonClicked(string obj )

        {

            await App.Current.MainPage.DisplayAlert("Message", "OnBuyButtonClicked " + obj.ToString(), "OK");

        }






LN Lakshmi Natarajan Syncfusion Team February 14, 2022 05:28 PM UTC

Hi Gabriel, 
 
You can achieve your requirement by defining the Command with the Object[] parameter because you are using multi binding.  
 
Please refer to the following code snippets for more reference, 
public Command<object[]> DigitCommand { get; set; } 
 
public ContactsViewModel() 
{ 
    DigitCommand = new Command<object[]>(OnButtonClicked); 
} 
 
private void OnButtonClicked(object[] obj) 
{ 
    System.Diagnostics.Debug.WriteLine("DigitCommand Key " + obj[0].ToString() + " pressed"); 
} 
 
 
Also, you can bind the BindingContext directly to the CommandParameter to access all the details of the underlying tapped object by using the following code snippets, 
 
//Code behind 
 
bookmarkItButton.SetBinding(SfButton.CommandParameterProperty, new Binding() { Source = bookmarkItButton, Path = "BindingContext" }); 
 
//ViewModel 
 
public Command<object> DigitCommand { get; set; } 
 
public ContactsViewModel() 
{ 
    DigitCommand = new Command<object>(OnButtonClicked); 
} 
 
private void OnButtonClicked(object obj) 
{ 
    var item = obj as Contacts; 
    System.Diagnostics.Debug.WriteLine("DigitCommand Key " + item.ContactName + " pressed"); 
} 
 
 
We have attached the tested sample in the following link, 
 
Please let us know if you need further assistance. 
 
Lakshmi Natarajan 
  
 


Loader.
Up arrow icon