当我通过按钮从ListView中单击时,在细节页面上的数据无法正确绑定时出现问题。 ListView完美地绑定,并且该对象被传递到详细信息页面。读取对象的ID,并从API调用对象的完整版本,并将其设置为对象的新实例。当我添加一个断点时,完整的对象可用,但是视图中的Labels没有被填充。这是ViewModel:
DetailsViewModel.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文件是
DetailPage.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函数中手动创建交易,但仍然没有任何约束。
答案 0 :(得分:0)
1)确保您的属性将实现INotifyPropertyChanged接口的更改通知UI。参见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));
}
}
}