带有mvvm指示灯的Xamarin android:只有在调用relaycommand的

时间:2019-01-06 19:39:40

标签: c# android xamarin mvvm binding

我设置了一个非常简单的应用程序来帮助我入门并尝试尝试。它有一个标签和两个按钮。这些按钮链接到主视图模型中的中继命令,这些按钮用于使用Mqtt向服务器发送消息,该消息按预期工作。标签用于显示从服务器接收的部分数据。尽管我可以在调试中看到该属性已设置,但标签不会在收到消息后立即更新,因此一切似乎都正常运行。只要按下两个按钮之一,标签就会更新。

我是整个Xamarin android系统的新手,并且在WPF应用程序中曾经使用过mvvm light。

主要活动:

public partial class MainActivity
{
    // UI Elements 
    public TextView ScanInfoLabel { get; private set; }
    public Button UnlockButton { get; private set; }
    public Button RegisterButton { get; private set; }

    // Keep track of bindings to avoid premature garbage collection
    private readonly List<Binding> _bindings = new List<Binding>();

    // Get view model
    private MainViewModel mainViewModel { get { return App.Locator.Main;}}

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get the UI elements by ID
        ScanInfoLabel = FindViewById<TextView>(Resource.Id.ScanInfoLabel);
        UnlockButton = FindViewById<Button>(Resource.Id.UnlockButton);
        RegisterButton = FindViewById<Button>(Resource.Id.RegisterButton);

        // Set Bindings for textviews
        _bindings.Add(
                this.SetBinding(
                    () => mainViewModel.ScanInfoLabel,
                    () => ScanInfoLabel.Text));

        // Set the bindings for commands
        UnlockButton.SetCommand("Click", mainViewModel.UnlockCommand);
        RegisterButton.SetCommand("Click", mainViewModel.RegisterTagCommand);
    }

在主视图模型中:

// RelayCommands
public RelayCommand UnlockCommand;
public RelayCommand RegisterTagCommand;
public RelayCommand MqttConnectCommand;

// Bindable properties
private string _scanInfoLabel = "Test";
public string ScanInfoLabel
{
    get { return _scanInfoLabel; }
    set { Set(ref _scanInfoLabel, value); }
}

// New scan message received
private void RFIDScanReceived(RFID.Scan scan)
{
    ScanInfoLabel = BitConverter.ToString(scan.UID);
}

我希望标签在接收到mqtt消息后立即显示数据(然后从mvvm light使用Messenger.Default.send <>()将其发送到mainviewmodel)。但是,在我单击按钮之一,然后显示正确的信息之前,UI上没有任何更改。

我真的不知道从哪里开始成为xamarin android的新手,我的搜索似乎都没有任何帮助。

任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:0)

  

ViewModel通常实现INotifyPropertyChanged接口,   这意味着该类每当一个事件触发一个PropertyChanged事件   属性的变化。 Xamarin.Forms中的数据绑定机制   将处理程序附加到此PropertyChanged事件,以便可以通知它   当属性更改时,并保持目标已更新为新   值。

解决方案:

使您的模型继承自INotifyPropertyChanged,并在集合部分中添加PropertyChanged。然后,一旦ScanInfoLabel的值更改,标签就会更新。

public class BaseViewModel : INotifyPropertyChanged
    {
        // Bindable properties
        private string _scanInfoLabel = "Test";
        public string ScanInfoLabel
        {
            get { return _scanInfoLabel; }
            set
            {
                _scanInfoLabel = ScanInfoLabel;

                PropertyChanged(this, new PropertyChangedEventArgs("ScanInfoLabel"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

您可以参考:data-bindings-to-mvvm

答案 1 :(得分:0)

Well I found out it was a threading issue since I set the property from a Messenger call. This apparently is not an issue in WPF which is why I was a bit stuck but using the DispatcherHelper did the trick.

// New scan message received
private void RFIDScanReceived(RFID.Scan scan)
{
    DispatcherHelper.CheckBeginInvokeOnUI(() => 
    {
        ScanInfoLabel = BitConverter.ToString(scan.UID);
    });
}