Xamarin Forms 中的数据绑定问题

DataBinding issue in Xamarin Forms

我有一个新的 Xamarin Forms 5 应用程序,但在数据绑定方面遇到了问题。

首先,我显示一条消息,告诉用户他的列表中有多少项。最初,这是 0。它由视图模型的 DisplayMessage 属性 显示。

然后,调用 Init() 方法,一旦 API 调用完成,MyList 中就会有一些项目。我放置了断点以确保 API 调用有效,并且我最终在 MyList 属性.

中得到了一些数据

因为我在我的 Init() 方法中更改了 message 的值,所以我希望消息会更改并显示列表中的项目数,但它并没有改变,即使我有一些MyList.

中的项目

我创建了一个新的 ViewModel,如下所示:

public class MyViewModel : BaseViewModel
{
   public List<MyItem> MyList { get; set; } = new List<MyItem>();

   string message = "You have no items in your list... ";
  
   public string DisplayMessage
   {
       get => message;
       set
       {
           if(message == value)
               return;

           message = value;
           OnPropertyChanged();
       }
   }

   public async void Init()
   {
       var data = await _myService.GetData();
       
       if(data.Count > 0)
          message = $"You have {data.Count} items in your list!";

       MyList = data;
   }
}

我的 MainPage 后面的代码如下所示:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
   MyViewModel _vm;
   MainPage()
   {
       InitializeComponent();
       _vm = new MyViewModel();
       this.BindingContext = _vm;
   }

   protected override void OnAppearing()
   {
      base.OnAppearing();
      _vm.Init();
   }
}

我没有更改基本视图模型中的任何内容,只是添加了我的服务,它看起来像这样:

public class BaseViewModel : INotifyPropertyChanged
{
    public IMyApiService MyApi => DependencyService.Get<IMyApiService>();

    bool isBusy = false;
    public bool IsBusy
    {
        get { return isBusy; }
        set { SetProperty(ref isBusy, value); }
    }

    string title = string.Empty;
    public string Title
    {
        get { return title; }
        set { SetProperty(ref title, value); }
    }
    protected bool SetProperty<T>(ref T backingStore, T value,
    [CallerMemberName] string propertyName = "",
    Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;
        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;
         changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

我很感激有人告诉我我的错误在哪里。谢谢。

没有看到 Xaml,我无法 100% 回答,但我看到了以下几点:

  1. 您正在通过字段设置“消息”,而不是 属性。由于您是直接设置字段,因此不会触发 OnPropertyChanged 事件,因此 UI 不会收到值已更改的通知。
  2. 我猜您正在将“MyList”绑定到某种 CollectionView 或其他东西?如果它是只读视图,则可以使用列表,因为该集合永远不会更新。但是,如果您计划在运行时添加或删除项目,出于与上述相同的原因,它需要是一个“ObservableCollection”,UI 不会收到列表中新项目的通知,但 ObservableCollection 会通知UI 的更改,因此它可以更新。
  3. Jason 在他的评论中提到了上面的内容。 MyList 属性 应该像使用 OnPropertyChanged 的​​其他属性一样设置。