Jason Richmeier
Jason Richmeier

Reputation: 1645

How To - Properly Bind Button Inside of ListView to View Model Property

I seem to be having issues with getting a command wired up to a button.

Suppose I have the following:

MainPageViewModel.cs

public class MainPageViewModel : ViewModelBase
{
    private ICollection<MenuItem> _menuItems;

    public MainPageViewModel(INavigationService navigationService) : base(navigationService)
    {
        TestCommand = new DelegateCommand(TestCommandExecute);
        Title = "Menu";
    }

    public ICollection<MenuItem> MenuItems
    {
        get
        {
            return _menuItems;
        }

        private set
        {
            SetProperty(ref _menuItems, value, nameof(MenuItems));

            return;
        }
    }

    public DelegateCommand TestCommand
    {
        get;

        private set;
    }

    private void TestCommandExecute()
    {
        return;
    }
}

MainPage.xaml

<?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="Menu.Views.MainPage" x:Name="Root" Title="{Binding Title}">
    <StackLayout>
        <Button Command="{Binding Mode=OneWay, Path=TestCommand}" Text="Test" />
        <ListView ItemsSource="{Binding Mode=OneWay, Path=MenuItems}" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <Button Command="{Binding Path=TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

The command will fire when I click the Test button but it will not fire when I click any of the buttons that are generated by way of the ListView. I have confirmed this by placing a break point on the TestCommandExecute method. I do not see any errors being generated.

Is this the proper way to wire up buttons inside of a list view to a command in the view model?

Upvotes: 1

Views: 1050

Answers (2)

user947737
user947737

Reputation: 364

Try using this:

<Button Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainPage}}}"/>

Upvotes: 1

Jason Richmeier
Jason Richmeier

Reputation: 1645

I figured this out via another Stack Overflow question...

The binding should be...

<Button Command="{Binding Path=BindingContext.TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />

...instead of...

<Button Command="{Binding Path=TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />

Notice the added BindingContext.

Upvotes: 1

Related Questions