【问题标题】:Xamarin Forms MVVM Databinding failing when I'm binding to a single object当我绑定到单个对象时,Xamarin Forms MVVM 数据绑定失败
【发布时间】:2019-03-20 22:08:56
【问题描述】:

当我通过按钮从 ListView 中单击时,我遇到了数据未正确绑定在详细信息页面上的问题。 ListView 完美绑定,对象被传递到详细信息页面。读取对象的 ID,并从 API 调用对象的完整版本并将其设置为对象的新实例。当我添加断点时,完整的对象可用,但视图上的标签未填充。这是 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 函数中手动创建交易,但仍然没有任何绑定。

【问题讨论】:

    标签: mvvm data-binding xamarin.forms


    【解决方案1】:

    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));
            }
    
        }
    }
    

    【讨论】:

    • 当然,有很多方法可以使用继承或 MVVM 框架来简化 UI 通知代码,但这是您的选择
    • 嗨,Rudy,已经解决了,谢谢。我必须承认,在填充 ListView 时不必做任何这些事情,我宁愿忽略了这个需求!我认为关键是在 UI 线程上运行任务,我曾在某一时刻实现了 INotifyPropertyChanged 接口,但当它不能单独工作时将其收回!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    相关资源
    最近更新 更多