我设置了一个非常简单的应用程序来帮助我入门并尝试尝试。它有一个标签和两个按钮。这些按钮链接到主视图模型中的中继命令,这些按钮用于使用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的新手,我的搜索似乎都没有任何帮助。
任何帮助将不胜感激,谢谢!
答案 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);
});
}