0
votes

NOTE: This is for Xamarin forms. The question which was believed to be a duplicate is actual dealing with a C# ListView

I have a List View (cross platform using Visual Studio 2017 for Mac Xamarin Forms) I have a rough understanding of data binding so I got the form to load data from a web service. Now I want to perform a few actions for each displayed row so I embedded a button in the ListView for each item. I cannot get how to add an action so that it performs some function for that row that was selected.

In the ListView I create the button this way:

<Button x:Name="prayUpButton" Command="{Binding _handle_prayupbutton_action}" Text="PU" Grid.Row="4" Grid.Column="0" />

in the code behind I have the following methods:

void handle_prayupbutton_action()
{

}

public Command _handle_prayupbutton_action
{    
        get { return new Command(() => handle_prayupbutton_action());
}

From my understanding you create a Command that will then trigger the action. What am I missing here? If I put a breakpoint on void handle_prayupbutton_action() it never hits it.

What is the best practice/correct way to add an action to a Xamarin Forms Cross Platform List View?

UPDATE 1: I changed the code below to this:

This is my header:

<?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="prayupapp.Pages.PrayersPage" x:Name="PrayersPagePage">

So I changed the button command:

<Button x:Name="prayUpButton" Command="{Binding Source={x:Static local.PrayersPagePage._handle_prayupbutton_action}}" Text="Pray Up" Grid.Row="4" Grid.Column="0" />

I also made the command routine a Static as Julipan suggested. I am actually regressing because the list view stopped loading from the previous page now. I find that if I return the button Command to its original code (which s evidently wrong) it does work. Something is wrong with the way I am doing the binding.

1
When you say code behind are you just referring to the Xaml.cs file? To use binding you have to setup the BindingContext of the view to a different class (ViewModel) and place the command there. developer.xamarin.com/guides/xamarin-forms/xaml/xaml-basics/… covers most of itShane Neuville
Did you set the binding context to the ListView or Page? The Item's BindingContext, is the item itself. So, when you use binding inside a item cell, the binding property must be accessible on the item level. Do you understand?Diego Rafael Souza
the question @GeraldVersluis linked to IS specifically about XFJason
Don't really understand your edit. Like @Jason states, the duplicate I am referring to is for Xamarin.Forms. A ListView is a Xamarin.Forms specific control. If you look closely, you will see the solution is the same. Note that each item in your ListView isn't bound to the viewmodel or code-behind but refers to the instance that is shown in the ListView Cell. That is why your Command isn't fired. It is looking in the class that is represented in the Cell. Please have another look, or explain how it is different.Gerald Versluis

1 Answers

1
votes

If all you need to do is to bind the Code Behind's Command to your Button's Command property then you need to define the command as Static in the "code behind":

static void handle_prayupbutton_action()
{

}

public static Command _handle_prayupbutton_action
{
    get
    {
        return new Command(() => handle_prayupbutton_action());
    }
}

And in your XAML you must add the source you are binding to:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:AppX"
         x:Class="AppX.MainPage">

    <StackLayout>
        <ListView ItemsSource="{Binding Source={x:Static local:MainPage.Items},
                                        Path=.}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Button Text="{Binding .}"
                                    Command="{Binding Source={x:Static local:MainPage._handle_prayupbutton_action}}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

This is working perfectly on my side. I hope you get the knowledge you are looking for.