Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Button Command Binding

I've got a pretty basic test page called SettingsPage which contains a button in the xaml as follows:

<Button Text="Toggle Compass" Command="{Binding toggleCompassCmd}"/>

A class CompassTest implements INotifyPropertyChanged and adds a new command called toggleCompassCmd:

using System;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace HelloWorld.Models
{
public class CompassTest : INotifyPropertyChanged
{
    // Set speed delay for monitoring changes.
    SensorSpeed speed = SensorSpeed.UI;

    public ICommand toggleCompassCmd { private set; get; }

    private CompassData m_data;
    protected CompassData compassData
    {
        get { return m_data; }
        private set { m_data = value; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public CompassTest()
    {
        // Register for reading changes, be sure to unsubscribe when finished
        Compass.ReadingChanged += onCompassReadingChanged;

        // setup toggle command
        toggleCompassCmd = new Command(
            execute: () =>
            {
                Console.WriteLine("This is execute of toggleCompassCmd!");
                toggleCompass();
            },
            canExecute: () =>
            {
                return true;     
            });

    }

    void onCompassReadingChanged(object sender, CompassChangedEventArgs e)
    {
        var data = e.Reading;
        Console.WriteLine($"Reading: {data.HeadingMagneticNorth} degrees");
        // Process Heading Magnetic North

        compassData = data;
        onPropertyChanged("compassData");
    }

    protected void onPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));
        }
    }

    public void toggleCompass()
    {
        Console.WriteLine("toggleCompass()");
        try
        {
            if (Compass.IsMonitoring)
                Compass.Stop();
            else
                Compass.Start(speed);
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            Console.WriteLine("FeatureNotSupportedException: " + fnsEx.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception: " + ex.ToString());
        }
    }
}
}

In the xaml class, I have a member of type CompassTest, which should receive the command, like so:

public SettingsPage()
    {
        InitializeComponent();

        compass = new CompassTest();
    }

However, everything compiles, but nothing fires. How do I "redirect" a command to a member?

like image 458
mefiX Avatar asked Dec 10 '18 14:12

mefiX


1 Answers

Set your pages' BindingContext to the object holding the command. In your case:

public SettingsPage()
{
    InitializeComponent();

    compass = new CompassTest();
    BindingContext = compass;
}
like image 184
Gerald Versluis Avatar answered Oct 03 '22 00:10

Gerald Versluis