问题描述
我已经使用Visual Studio中可用的模板启动了Xamarin项目。 我写了一些从REST API获取数据的服务。我已经将这些值打印到控制台上,并且能够看到这些服务按其应有的方式工作。
但是,我无法显示从Api获取的用户名。 我正在尝试在viewmodel类中做到这一点。
using MyApp.Models;
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
using MyApp.Services;
using System.Threading.Tasks;
namespace MyApp.viewmodels
{
public class Aboutviewmodel : Baseviewmodel
{
static readonly UserService CurrentUser = new UserService();
public Aboutviewmodel()
{
//GetData().Wait();
Title = "My App";
OpenWebCommand = new Command(async () => await browser.OpenAsync("https://aka.ms/xamain-quickstart"));
IsConnected = false;
GetData();
}
protected async void GetData()
{
user = await CurrentUser.GetUser();
Name = user.fullName;
}
public ICommand OpenWebCommand { get; }
public bool IsConnected { get; set; }
public string Name { get; set; }
public User user { get; set; }
}
}
<Label Text="{Binding Name}" FontSize="Title"/>
我知道这是一种不好的做法,但是我试图破解它。它仍然不起作用,并且什么也不显示。到目前为止,这是我所管理的唯一一件事,不会崩溃或使应用程序冻结。当最终从异步void或任务设置“名称”时,如何绑定到变量“名称”?
解决方法
如果您使用的是MVVM框架,则您的BaseViewModel
应该实现INotifyPropertyChanged
接口或从已经实现该接口的类继承。
这可能类似于:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T backingField,T newValue,[CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(backingField,newValue))
{
return false;
}
backingField = newValue;
RaisePropertyChanged(propertyName);
return true;
}
}
然后,对于您在ViewModel中的属性,可以使用SetProperty
来确保PropertyChanged
在其值更改时被触发。它们绑定到的UI才需要这样做,以找出某些更改。
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name,value);
}
如果您不想使用SetProperty
,只需使用RaisePropertyChanged
:
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
RaisePropertyChanged();
}
}