Xamarin.Forms ListView绑定问题

dcpartners

我们是Xamarin的新手。将响应数据从Web服务绑定到ListView时遇到问题。

我们进行了调试,可以看到Web服务已成功对数据进行响应,但从未填充数据。

有任何想法吗?

我们一定缺少一件事。我们设法在数据中显示了一个条目,而其他视图(在项目的其他部分)却不在IEnumerable<>List<>

这是代码:

视图-RoundsPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:AthlosifyMobile.ViewModels"
             x:Class="AthlosifyMobile.Views.RoundsPage">

    <ContentPage.BindingContext>
        <viewModels:RoundsViewModel />
    </ContentPage.BindingContext>

    <StackLayout>

        <Entry Text="{Binding AccessToken}" />
        <Button Command="{Binding GetRoundsCommand}" Text="Get all rounds" />
        <Label Text="Rounds: "></Label>
        <ListView ItemsSource="{Binding Rounds}" HasUnevenRows="true"  >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <Label Text="Round 1:"></Label>
                            <Label Text="{Binding Name}"></Label>
                            <Label Text="{Binding DailyHandicap}"></Label>
                            <Label Text="{Binding PlayedUTC}"></Label>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>`

ViewModel-RoundsViewModel.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Input;
using AthlosifyMobile.Annotations;
using Xamarin.Forms;
using AthlosifyMobile.Services;
using AthlosifyMobile.Models;

namespace AthlosifyMobile.ViewModels
{ 
    public class RoundsViewModel : INotifyPropertyChanged
    {
        ApiServices _apiServices = new ApiServices();
        public event PropertyChangedEventHandler PropertyChanged;
        private IEnumerable<Round> _rounds;
        public string AccessToken { get; set; }
        public IEnumerable<Round> Rounds
        {
            get
            {
                return _rounds;
            }
            set
            {
                _rounds = value;
                OnPropertyChanged();
            }
        }

        public ICommand GetRoundsCommand
        {
            get
            {
                return new Command(async() =>
                {
                    Rounds = await _apiServices.GetRoundsAsync(AccessToken);
                });
            }
        }

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

模型-Course.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace AthlosifyMobile.Models
{
    public class Round : EntityBase
    {
        public Guid RoundID { get; set; }
        public Guid UserID  { get; set; }
        public Guid RoundCategoryID { get; set; }
        public Guid CourseID { get; set; }
        public string Name { get; set; }
        public string Notes { get; set; }
        public int DailyHandicap { get; set; }
        public DateTime PlayedUTC { get; set; }
        public RoundCategory RoundCategory { get; set; }
        public Course Course { get; set; }

        public ICollection<RoundHole> RoundHoles { get; set; }
    }   

    public abstract class EntityBase
        {
            public DateTime CreatedUTC { get; set; }

            public DateTime LastModifiedUTC { get; set; }
        }
}

服务-apiservices.cs:

using AthlosifyMobile.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace AthlosifyMobile.Services
{

        public async Task<IEnumerable<Round>> GetRoundsAsync(string accessToken)
        {
            var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            var json = await client.GetStringAsync("http://localhost:5609/api/Rounds");
            var list = JsonConvert.DeserializeObject<IEnumerable<Round>>(json);

            return list;
        }
    }
}
阿克斯塔玛

您将需要诊断这是将View连接到ViewModel还是问题,或者您的数据服务是否无法正常工作。无论哪种方式,您都应该做一些事情来解决这个问题!

首先,您使用IEnumerable,而不是ObservableCollection<T>. You should always be using对绑定列表视图使用ObservableCollection`。这是在xamarin文档解释这里(他们会自动通知时,他们的内容改变和更新视图)。

因此,您应该进行以下更改:

private ObservableCollection<Round> _rounds;
public ObservableCollection<Round> Rounds
{
    get { return _rounds; }
    set
    {
        _rounds = value;
        OnPropertyChanged("Rounds");
    }
}

接下来,您应该验证绑定正确。如果您对xamarin不熟悉,我不建议您直接使用实时数据。首先,您应该尝试将一些静态对象添加到视图模型并尝试将它们绑定!

断开您的API代码,然后调用创建一些Round对象的方法。这是一个示例方法(在设计ListViews UI时,我一直使用类似的方法)。

public RoundsViewModel()
{
    _rounds = CreateSampleData();
}

private ObservableCollection<Round> CreateSampleData()
{
    ObservableCollection<Round> dummyData = new ObservableCollection<Round>();

    dummyData.Add(new Round() { Name="User", handicap=1, PlayedUTC=DateTime.Now });
    dummyData.Add(new Round() { Name="User", handicap=1, PlayedUTC=DateTime.Now });
    dummyData.Add(new Round() { Name="User", handicap=1, PlayedUTC=DateTime.Now });

    return dummyData;
}

此时,您将在ListView中看到项目,这意味着您的API代码/的实现存在问题INotifyPropertyChanged如果看不到任何内容,则可能是绑定问题,需要验证视图是否确实连接到了视图模型。

Mvvm帮手

看到其中的一些代码会让我为您感到非常抱歉,您绝对应该考虑使用MVVM帮助器,例如Prism或MVVMCross。我个人使用Prism,它提供了ViewModelBase所有ViewModel都继承自的。这意味着所有INotifyPropertyChanged代码都对您隐藏(减少了样板)。它还具有依赖服务,这意味着将视图挂接到视图模型就像在app.cs中注册一样简单。

如果您对棱镜感兴趣,与Brian Lagunas观看此视频,看看Prism可以为您做什么!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章