【问题标题】:Xamarin Forms - How to display data binded (List from HttpClient)?Xamarin Forms - 如何显示绑定的数据(来自 HttpClient 的列表)?
【发布时间】:2019-10-31 03:54:09
【问题描述】:

json 反序列化后无法在列表视图中显示数据。我需要如何设置才能看到它?

我正在使用绑定上下文从 http 客户端对我的响应进行数据绑定,因此我可以在我的列表视图中使用它。

MainPage.xaml

<ContentPage
        Title="Home"
     >
        <Grid>
            <ListView ItemsSource="{Binding .}">
            <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <Label Text="{Binding Description}"/>
                            <Label Text="{Binding Value}"/>
                        </StackLayout>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </ContentPage>

MainPage.cs

public MainPage()
        {
            DataService ds = new DataService();

            BindingContext = ds.GetBillsAsync();

            InitializeComponent();

            Chart1.Chart = new BarChart { Entries = entries, LabelTextSize = (float)Convert.ToDouble(Device.GetNamedSize(NamedSize.Large, typeof(Label))), BackgroundColor = SKColors.Transparent };



        }

DataService.cs

public class DataService
    {
        HttpClient client = new HttpClient();

        public async Task<List<Bill>> GetBillsAsync()
        {
            try
            {
                string url = "my url";

                var response = await client.GetStringAsync(url).ConfigureAwait(continueOnCapturedContext: false); ;
                var bills = JsonConvert.DeserializeObject<List<Bill>>(response);
                return bills;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }

我没有收到任何错误消息,除了此输出消息"Binding: System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[Test.Models.Bill]] can not be converted to type 'System.Collections.IEnumerable'",我认为这不是问题,因为在调试时我可以看到我的列表被正确填充。

你能帮帮我吗?

提前谢谢你

【问题讨论】:

  • 可以通过将其绑定到如下列表视图 ItemsSource 来工作吗?
  • 这真的很简单,是的,现在我只想显示该信息,但我无法在 MainPage 中继承 ContentPage。它给了我这个错误Partial declarations of 'MainPage' must not specify different base classes
  • 你的 MainPage 是什么?它是 ContentPage 吗?如果是内容页面,它的 xaml 会在下面我更新
  • xamarin.com/schemas/2014/forms" xmlns:x="schemas.microsoft.com/winfx/2009/xaml" xmlns:d="xamarin.com/schemas/2014/forms/design" xmlns:mc="schemas.openxmlformats.org/markup-compatibility/2006" xmlns:forms= "clr-命名空间:Microcharts.Forms;assembly=Microcharts.Forms" xmlns:xf ="clr-命名空间:BottomBar.XamarinForms;assembly=BottomBar.XamarinForms" mc:Ignorable="d" x:Class="Test.MainPage" >
  • 你试着让你的MainPage实现BottomBarPage,比如public partial class MainPage: BottomBarPage。然后试试

标签: c# list xamarin.forms binding httpclient


【解决方案1】:

Nikhil的方法是一种方法,如果你只想设置从http客户端请求到listview的List,你可以绑定到ListView的ItemsSource属性。

MainPage.xaml.cs 中:

public partial class MainPage: ContentPage
{
   DataService ds = new DataService();
   public MainPage()
    {

        InitializeComponent();
        Chart1.Chart = new BarChart { Entries = entries, LabelTextSize = (float)Convert.ToDouble(Device.GetNamedSize(NamedSize.Large, typeof(Label))), BackgroundColor = SKColors.Transparent };
    }

   protected override async void OnAppearing()
    {
        base.OnAppearing();
        listview.ItemsSource = await ds.GetBillsAsync();
    }
}

MianPage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         Title="Home"
         x:Class="App18.MainPage">
  <ContentPage.Content>
    <StackLayout>
        <ListView x:Name="listview">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Label Text="{Binding Description}"/>
                        <Label Text="{Binding Value}"/>
                    </StackLayout>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
 </ContentPage.Content>
</ContentPage>

【讨论】:

    【解决方案2】:

    您需要更改 GetBillsAsync 方法以检索 Array,然后使用 Array.ToList() 和 System.Linq 转换为 List。

    您需要为此实现一个 ViewModel。您可以将 NuGet MVVM 帮助程序用于 BaseViewModel 或实现您自己的。

    using System.Windows.Input;
    using MvvmHelpers.Interfaces;
    
    namespace NameSpace.ViewModel
    {
        public partial class HomeViewModel : BaseViewModel
        {
    
            private ObservableCollection<Bill> _listOfbills = new ObservableCollection<Bill>();
            public ObservableCollection<Bill> ListOfbills
            {
                get => _listOfbills;
                set => SetProperty(ref _listOfbills, value);
            }
            public HomeViewModel()
            {
                DataService ds = new DataService();
                ListOfbills = ds.GetBillsAsync()
            }
        }
    }
    

    然后你的 MainPage 变成:-

    HomeViewModel 虚拟机; 公共主页() {

                BindingContext = vm = new HomeViewModel();
    
                InitializeComponent();
    
                Chart1.Chart = new BarChart { Entries = entries, LabelTextSize = (float)Convert.ToDouble(Device.GetNamedSize(NamedSize.Large, typeof(Label))), BackgroundColor = SKColors.Transparent };
    
    
    
            }
    

    然后在 Xaml 中,您可以按如下方式更改此行:-

    <ListView ItemsSource="{Binding ListOfbills}">
    

    这些更改应该有效。如果您遇到困难,请告诉我。谢谢!

    【讨论】:

    • 它给了我 2 个错误:1. "Cannot implicitly convert type 'System.Threading.Tasks.Task&lt;System.Collections.Generic.List&lt;Test.Models.Bill&gt;&gt;' to 'System.Collections.ObjectModel.ObservableCollection&lt;Test.Models.Bill&gt;'" 2. public HomeViewModel 必须有一个返回类型
    • 更新代码中的以下内容:- 1. ListOfbills = new ObservableCollection(ds.GetBillsAsync()); 2.从“public partial class HomeViewModel : BaseViewModel”中去掉关键字partial
    • 更新:第二个只是命名问题,抱歉 xD。我已经在 GetBillsAsync 中使用 linq 对其进行了转换,但它给了我同样的错误。
    • 你需要写 ListOfbills = new ObservableCollection(ds.GetBillsAsync());因为要从 List 中获取 ObservableCollection,我们需要这样做
    • 抱歉,我可能遗漏了一些东西。我已经按照你说的实现了ListOfbills = new ObservableCollection&lt;Bill&gt;( ds.GetBillsAsync()); ,现在它给了我这个转换错误cannot convert from 'System.Threading.Tasks.Task&lt;System.Collections.Generic.List&lt;Test.Models.Bill&gt;&gt;' to 'System.Collections.Generic.IEnumerable&lt;Test.Models.Bill&gt;'
    猜你喜欢
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 2018-03-09
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    相关资源
    最近更新 更多