Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Button command binding doesn't work in Xamarin.Forms

I'd like to bind a command to the command property of my button. This seemed pretty straightforward since I've done this many times before in WPF and the method here is very similar. Let me show some code snippets.

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="MyApp.View.CustomPage"
         Title="Something">

<ContentPage.Content>
    <StackLayout>
        <Button x:Name="numBtn" Text="Increase number" Command="{Binding IncreaseCommand}" />
        <Label x:Name="numLabel" Text="{Binding numberText}" />
    </StackLayout>
</ContentPage.Content>
</ContentPage>

Code-behind

public partial class CustomPage : ContentPage
{   
    public CustomPage ()
    {
        InitializeComponent ();
        BindingContext = ViewModelLocator.ViewModel();  //ViewModelLocator is singleton, gives
                                                        //you a ViewModel instance
    }
}

ViewModel

public ICommand IncreaseCommand { get; private set; }
private int number;
public string numberText { get; private set;}

the constructor:

public ViewModel()
{
    IncreaseCommand = new Command (() => IncreaseExecuted ());
    number = 0;
    numberText = number.ToString ();
    OnPropertyChanged (numberText);
}

and then

private void IncreaseExecuted()
{
    number++;
    numberText = number.ToString ();
    OnPropertyChanged (numberText);
}

When I run the app using the Xamarin Android Player (KitKat) I see the button, and the label reading 0. Then I press the button and nothing happens. I tried checking what happens with breakpoints but the app doesn't pause, not even when they're in the constructor of my ViewModel. I guess it's something to do with the emulator. Anyway, I think the binding is ok since I can see a "0" on the screen. What could be the problem? Let me show my ViewModelBase class just in case:

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Maybe my numberText property doesn't get updated when I call OnPropertyChanged? But I've used the exact same ViewModelBase class several times before and it always worked fine. One last thing, my CustomPage page is wrapped inside a NavigationPage which is a child of a TabbedPage:

MainPage.xaml.cs

this.Children.Add (new NavigationPage (new CustomPage ()) {Title="Something"} );

This shouldn't affect anything but there it is just in case. So what's wrong with my command binding? Thank you in advance!

like image 358
Gábor Birkás Avatar asked Dec 13 '14 15:12

Gábor Birkás


People also ask

How does binding work in xamarin forms?

Data binding is the technique of linking properties of two objects so that changes in one property are automatically reflected in the other property. Data binding is an integral part of the Model-View-ViewModel (MVVM) application architecture.

How do you bind property in xamarin forms?

The SetBinding method is called on the binding target but specifies both the target property and the source property. The target property is specified as a BindableProperty object: Label. RotationProperty . The source property is specified as a string and indicates the Value property of Slider .

How do I set binding context in xamarin forms?

In code, two steps are required: The BindingContext property of the target object must be set to the source object, and the SetBinding method (often used in conjunction with the Binding class) must be called on the target object to bind a property of that object to a property of the source object.

What is the default binding mode in xamarin forms?

The default binding mode is OneWayToSource . When a data binding is set on the SelectedItem property to reference a source property in a ViewModel, then that source property is set from the ListView selection. However, in some circumstances, you might also want the ListView to be initialized from the ViewModel.


1 Answers

This answer is not directly related to the problem of the original question, however this question is the one that ranks highest in search engines and the title of this question is ambiguous to the question that this answer answers.

I was having issues with a Command that wouldn't fire the associated command action. My problem was that I had defined the Command as a field instead of a property.

Works:

public Command MyCommand { get; set; }

Doesn't work:

public Command MyCommand;

Hope this helps someone else.

like image 138
Hein Andre Grønnestad Avatar answered Sep 30 '22 01:09

Hein Andre Grønnestad