使用 Xamarin 将文本字段绑定到从 REST Api 获取的值
Bind text field to a value that is fetched from a REST Api using Xamarin
我已经使用 Visual Studio 中提供的模板启动了一个 Xamarin 项目。
我编写了一些从 REST api 获取数据的服务。我已将这些值打印到控制台,我能够看到服务正常工作。
但是,我无法显示从 Api 中获取的用户名。
我正在尝试在 ViewModel class.
中执行此操作
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; }
}
}
这是 .xaml 文件中显示的行:
<Label Text="{Binding Name}" FontSize="Title"/>
我知道这是不好的做法,但我试图让它正常工作。它仍然不起作用,并且不显示任何内容。这是迄今为止我所管理的唯一不会崩溃或使应用程序冻结的东西。当最终从异步无效或任务中设置“名称”时,如何绑定到变量“名称”?
如果您使用的是某种 MVVM 框架,您的 BaseViewModel
可能应该实现 INotifyPropertyChanged
接口或从已经实现它的 class 继承。
这可能类似于:
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();
}
}
我已经使用 Visual Studio 中提供的模板启动了一个 Xamarin 项目。 我编写了一些从 REST api 获取数据的服务。我已将这些值打印到控制台,我能够看到服务正常工作。
但是,我无法显示从 Api 中获取的用户名。 我正在尝试在 ViewModel class.
中执行此操作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; }
}
}
这是 .xaml 文件中显示的行:
<Label Text="{Binding Name}" FontSize="Title"/>
我知道这是不好的做法,但我试图让它正常工作。它仍然不起作用,并且不显示任何内容。这是迄今为止我所管理的唯一不会崩溃或使应用程序冻结的东西。当最终从异步无效或任务中设置“名称”时,如何绑定到变量“名称”?
如果您使用的是某种 MVVM 框架,您的 BaseViewModel
可能应该实现 INotifyPropertyChanged
接口或从已经实现它的 class 继承。
这可能类似于:
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();
}
}