【问题标题】:Xamarin Button Command BindingXamarin 按钮命令绑定
【发布时间】:2019-05-11 11:08:48
【问题描述】:

我有一个名为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)。

标签: c# xamarin xamarin.forms command


【解决方案1】:

将页面的BindingContext 设置为持有该命令的对象。在你的情况下:

public SettingsPage()
{
    InitializeComponent();

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

【讨论】:

  • 谢谢,我明白了!但这提出了一个新问题:如果我希望将新命令定向到与CompassTest 不同的类怎么办?一个页面可以有多个BindingContexts吗?
  • 不,通常你会有一个页面和一个页面模型(或视图和视图模型)并且该页面模型将包含所有命令和逻辑等。你的页面只能有一个BindingContext。所以,这是你需要考虑架构方面的事情。您可以通过将命令移动到您的页面或使用按钮上的事件(如 Tapped)在同一页面中拥有多个,但这会降低代码的可重用性和可维护性。
  • 非常感谢!这确实很高兴知道!您可以轻松地让单页模型将所有事件重定向/分派给成员。
  • 您可能希望查看像 mvvm 这样的模式,它非常适合 Xamarin.Forms。如果这对您有帮助,也请接受作为答案!
猜你喜欢
  • 2019-07-30
  • 2015-06-21
  • 2017-04-16
  • 2013-10-09
  • 2020-03-06
  • 2021-07-21
  • 2021-02-11
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多