mvvm - 当我绑定到单个对象时,Xamarin Forms MVVM 数据绑定失败
问题描述
当我通过按钮从 ListView 中单击时,我在详细信息页面上遇到数据未正确绑定的问题。ListView 完美绑定,对象被传递到详细信息页面。读取对象的 ID,并从 API 调用对象的完整版本并将其设置为对象的新实例。当我添加断点时,完整的对象可用,但视图上的标签未填充。这是视图模型:
详细信息ViewModel.cs
public class DetailsViewModel
{
public Deal Deal { get; set; }
public int DealId { get; set; }
public DetailsViewModel(int id)
{
Deal = new Deal();
DealId = id;
}
public async void GetDeal()
{
var deal = await Deal.GetDeal(DealId);
if(deal != null)
{
Deal = deal;
}
}
}
代码隐藏如下所示:
DetailPage.Xaml.cs
DetailsViewModel viewModel;
int dealId;
public DetailPage(int id)
{
InitializeComponent();
dealId = id;
viewModel = new DetailsViewModel(dealId);
BindingContext = viewModel;
}
protected override void OnAppearing()
{
base.OnAppearing();
viewModel.GetDeal();
}
Xaml 文件是
详细页面.Xaml
<ContentPage.Content>
<ScrollView>
<StackLayout x:Name="detailsLayout">
<Label Text="{Binding Deal.Name}" />
</StackLayout>
</ScrollView>
</ContentPage.Content>
当我在 DetailsViewModel 上的 Deal = deal 中放置断点时,Deal 对象存在并且具有正确的数据,但我只是得到一个空白屏幕。我尝试了带有 Text="{Binding Name}" 和 Text="{Binding Deal.Name}" 的标签。
我还尝试在 ViewModel 的 GetDeal 函数中手动创建交易,但仍然没有任何绑定。
解决方案
1) 确保您的属性通知 UI 实现 INotifyPropertyChanged 接口的更改。请参阅https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
2) 确保使用 Device.BeginInvokeOnMainThread 在 UI 线程上完成设置。https://docs.microsoft.com/fr-fr/dotnet/api/xamarin.forms.device.begininvokeonmainthread?view=xamarin-forms
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
namespace YourNamespace
{
public class DetailsViewModel : INotifyPropertyChanged
{
private Deal _deal;
public Deal Deal
{
get => _deal;
set
{
if (_deal != value)
{
_deal = value;
OnPropertyChanged();
}
}
}
public int DealId { get; set; }
public DetailsViewModel(int id)
{
//!! useless assignation
//Deal = new Deal();
DealId = id;
}
public async void GetDeal()
{
var deal = await Deal.GetDeal(DealId);
if (deal != null)
{
//Ensure we are on UI thread
Device.BeginInvokeOnMainThread(() => Deal = deal);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
推荐阅读
- docker - FatalErrorException 错误:超过 30 秒的最大执行时间
- angular - 当响应不匹配时,角度可观察接口不会强制任何错误
- java - 如果更改了 url,那么 Glide 是否有任何选项,然后缓存将被清除,否则会加载旧图像?
- swift - 符合 Swift 中关联类型协议的异构数组
- coding-style - oop 中更好的编码风格是什么:一种方法有一个参数 VS 两种方法没有参数?
- python - 如何在熊猫数据框中同时使用部分列名,dcast和重值进行分组
- prestashop - 在 Prestashop 1.7.6 购物车上显示产品可用性
- excel - 如何将时间写入 IF 语句以便识别它
- postgresql - PostgreSQL 查询返回 ERROR: could not identify an equal operator for type json
- node.js - NodeJs:无法在 AWS Lambda 环境中生成 Exiftool