Xamarin按钮命令绑定

7
我可以帮您翻译成中文。这段内容是关于编程的,讲述了一个名为SettingsPage的基本测试页面,其中包含以下XAML代码的按钮:
<Button Text="Toggle Compass" Command="{Binding toggleCompassCmd}"/>

一个名为CompassTest的类实现了INotifyPropertyChanged接口,并添加了一个名为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());
        }
    }
}
}

在xaml类中,我有一个类型为CompassTest的成员,应该像这样接收命令:
public SettingsPage()
    {
        InitializeComponent();

        compass = new CompassTest();
    }

然而,所有内容都编译通过,但没有任何响应。我该如何将命令“重定向”到成员?

你还没有设置绑定上下文。你需要将你的设置页面与 CompassTest 进行链接。我建议使用一些 MVVM 框架,如 CrossMVVM 或 FreshMVVM 或其他任何框架。(个人推荐是 Fresh)。 - Woj
1个回答

4

将页面的BindingContext设置为保存命令的对象。在您的情况下:

public SettingsPage()
{
    InitializeComponent();

    compass = new CompassTest();
    BindingContext = compass;
}

谢谢,我明白了!但这引出了一个新问题:如果我想让一个新命令指向不同于CompassTest的类,该怎么办?一个页面可以有多个BindingContext吗? - mefiX
1
不,通常你会有一个页面和一个页面模型(或视图和视图模型),而该页面模型将保存所有命令、逻辑等。您的页面只能有一个BindingContext。因此,在架构方面,这是您需要考虑的事情。您可以通过将命令移动到页面上或在按钮上使用Tapped等事件来在同一页中拥有多个,但这会降低代码的可重用性和可维护性。 - Gerald Versluis
非常感谢!确实很好知道!您可以轻松地将单页模型重定向/分派所有事件到成员。 - mefiX
1
你可能想要看一下像 mvvm 这样的模式,它非常适合 Xamarin.Forms。如果这对你有帮助,请接受为答案! - Gerald Versluis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接