Xamarin.Forms:如何填充一个饼图从网页API数据? [英] Xamarin.Forms: How To Populate A Pie Chart From Web API Data?

查看:479
本文介绍了Xamarin.Forms:如何填充一个饼图从网页API数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天每个人。我创建一个Xamarin.Forms便携式应用。而我目前正在编写一个饼图(OxyPlot),其中包含的静态数据



我想要做的就是有一个动态数据在每一个馅饼切片我有。这意味着,该数据应该来自我的数据库。



我已经能够从我的数据库中检索数据并显示它作为一个名单,我使用创建移动应用 < STRONG>网页API 像这样的:



ClientListPage.xaml

 <?XML版本=1.0编码=UTF-8>?; 
< ContentPage的xmlns =htt​​p://xamarin.com/schemas/2014/forms
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2009/xaml
X:类=XamarinFormsDemo.Views.ClientListPage
的xmlns:的ViewModels =CLR的命名空间:XamarinFormsDemo.ViewModels;装配= XamarinFormsDemo
的xmlns:控制=CLR的命名空间:ImageCircle.Forms .Plugin.Abstractions;装配= ImageCircle.Forms.Plugin.Abstractions
的BackgroundImage =bg3.jpg
标题=客户端的List1>


< StackLayout>

<搜索栏占位=搜索文本={结合关键词}SearchCommand ={结合SearchCommand}X:NAME =txtSearch/>

< ListView控件的ItemsSource ={结合CustomerList,模式=双向}
HasUnevenRows =真
IsPullToRefreshEnabled =真
X:NAME =ListView控件>


< ListView.ItemTemplate>
<&DataTemplate的GT;
< ViewCell>
<网格填充=10RowSpacing =10ColumnSpacing =5>
< Grid.RowDefinitions>
< RowDefinition高度=自动/>
< RowDefinition高度=*/>
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition WIDTH =自动/>
< ColumnDefinition WIDTH =*/>
< /Grid.ColumnDefinitions>

<控制:CircleImage来源=的icon.png
HeightRequest =66
Horizo​​ntalOptions =CenterAndExpand
看点=AspectFill
WidthRequest =66
Grid.RowSpan =2
/>




<标签Grid.Column =1
文本={结合CUSTOMER_NAME}
TEXTCOLOR =# 24e97d
字号=24/>



将;标签Grid.Column =1
Grid.Row =1
文本={结合CUSTOMER_CODE}
TEXTCOLOR =白
字号=18
透明度=0.6/>


<标签Grid.Column =1
Grid.Row =2
文本={结合CUSTOMER_MOBILE_NUMBER}
TEXTCOLOR =白
字号=18
透明度=0.6/>


<标签Grid.Column =1
Grid.Row =3
文本={结合CUSTOMER_EMAIL_ADDRESS}
TEXTCOLOR =白
字号=18
透明度=0.6/>


< /网格和GT;
< / ViewCell>
< / DataTemplate中>
< /ListView.ItemTemplate>

< /&的ListView GT;
< / StackLayout>


< / ContentPage>



ClientListPage.xaml.cs



 使用Newtonsoft.Json; 
使用OxyPlot;使用OxyPlot.Series
;
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Net.Http;使用System.Net.Http.Headers
;
使用System.Text;使用System.Threading.Tasks
;
使用System.Windows.Input;使用Xamarin.Forms
;使用XamarinFormsDemo.Models
;使用XamarinFormsDemo.ViewModels
;



命名空间XamarinFormsDemo.Views
{
公共部分类ClientListPage:ContentPage
{

CustomerVM视图模型;
公共ClientListPage()
{
NavigationPage.SetHasNavigationBar(这一点,真正的);


的InitializeComponent();
视图模型=新CustomerVM();
的BindingContext =视图模型;
}

异步覆盖保护无效OnAppearing()
{
base.OnAppearing();

VAR JSON =等待GetCustomerAsync();

VAR的客户= JsonConvert.DeserializeObject<客户[]>(JSON);

的foreach(在客户客户C)
viewModel.CustomerList.Add(C);
}

异步任务<串GT; GetCustomerAsync()
{
VAR的客户=新的HttpClient();

client.BaseAddress =新的URI(http://192.168.1.11:50857/);

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));

HttpResponseMessage响应=等待client.GetAsync(API /客户);
如果(response.IsSuccessStatusCode)
{
返回等待response.Content.ReadAsStringAsync();
}
,否则返回response.ReasonPhrase;
}


}
}

CustomerVM.cs

 使用系统; 
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.ComponentModel;使用System.Diagnostics程序
;
使用System.Linq的;
使用System.Net.Http;使用System.Runtime.CompilerServices
;
使用System.Text;使用System.Threading.Tasks
;
使用System.Windows.Input;使用Xamarin.Forms
;使用XamarinFormsDemo.Models
;使用XamarinFormsDemo.Services
;使用XamarinFormsDemo.Views
;


命名空间XamarinFormsDemo.ViewModels
{
公共类CustomerVM:INotifyPropertyChanged的
{


私人的ObservableCollection<客户> _customerList; //保存所有客户
私人的ObservableCollection<客户> _searchedCustomerList; //保留一份用于搜索
私人客户_selectedCustomer =新客户();

私人字符串_keyword =;
公共字符串关键字
{
得到
{
返回_keyword;
}

{
this._keyword =价值;

//而改变关键字过滤,我们的员工
//过滤器();
}
}




公众的ObservableCollection<客户> CustomerList
{
得到
{
返回_customerList;
}

{
_customerList =价值;
OnPropertyChanged();
}
}

公共CustomerVM()
{
CustomerList =新的ObservableCollection<客户>();
}



公共事件PropertyChangedEventHandler的PropertyChanged;

受保护的虚拟无效OnPropertyChanged([CallerMemberName]字符串参数propertyName = NULL)
{
VAR处理器=的PropertyChanged;
如果(处理!= NULL)处理(这一点,新PropertyChangedEventArgs(propertyName的));
}

}
}



但是,这一次,我需要做的是在一个饼图。



我真的没有一个想法如何做到这一点。但我认为上面我从我的Web API获取数据的方式对我要去如何做到这一点,我图的相似性。希望你能帮助我。



非常感谢。以上是我的一些代码:



SalesPerProductViewModel.cs



 使用OxyPlot;使用OxyPlot.Annotations 
;使用OxyPlot.Axes
;使用OxyPlot.Series
;
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.ComponentModel;
使用System.Linq的;使用System.Runtime.CompilerServices
;
使用System.Text;使用System.Threading.Tasks
;使用XamarinFormsDemo.Models
;

命名空间XamarinFormsDemo.ViewModels
{
公共类SalesPerProductViewModel:INotifyPropertyChanged的
{

私人的ObservableCollection<销售与GT; _salesList; //保存所有客户


公众的ObservableCollection<销售与GT; SalesPerProductModel
{
得到
{
返回_salesList;
}

{
_salesList =价值;
OnPropertyChanged();
}
}

公共SalesPerProductViewModel()
{

SalesPerProductModel =新的ObservableCollection<销售及GT;();


}




公共事件PropertyChangedEventHandler的PropertyChanged;

保护无效OnPropertyChanged([CallerMemberName]字符串参数propertyName = NULL)
{
的PropertyChanged .Invoke(这一点,新PropertyChangedEventArgs(propertyName的))?;
}



}
}

SalesPerProductPage.xaml (这是动态图表应显示)

 <?XML版本=1.0编码=UTF-8>?; 
< ContentPage的xmlns =htt​​p://xamarin.com/schemas/2014/forms
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2009/xaml
的xmlns:氧=CLR的命名空间:OxyPlot.Xamarin.Forms;装配= OxyPlot.Xamarin.Forms
的xmlns:的ViewModels =CLR的命名空间:XamarinFormsDemo.ViewModels;装配= XamarinFormsDemo
X:类=XamarinFormsDemo.Views.SalesPerProductPage
的BackgroundImage =bg3.jpg
标题=销售每产品>


< ContentPage.BindingContext>
<的ViewModels:SalesPerProductViewModel />
< /ContentPage.BindingContext>



<标签文本=总销售额LABEL这里!
TEXTCOLOR =#24e97d/>

<氧:PlotView模型={结合SalesPerProductModel}/>
< / ContentPage>



SalesPerProductPage.xaml.cs



 使用OxyPlot;使用OxyPlot.Xamarin.Forms 
;
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;使用XamarinFormsDemo.ViewModels
;使用Xamarin.Forms
;使用XamarinFormsDemo.Models
;
使用Newtonsoft.Json;
使用System.Net.Http;使用System.Net.Http.Headers
;使用OxyPlot.Series
;

命名空间XamarinFormsDemo.Views
{
公共部分类SalesPerProductPage:ContentPage
{
私人PlotModel modelForSales;
SalesPerProductViewModel viewModelforSales;

公共SalesPerProductPage()
{
的InitializeComponent();
viewModelforSales =新SalesPerProductViewModel();
的BindingContext = viewModelforSales;


} // SalesPerProductPage结束()


异步覆盖保护无效OnAppearing()
{
群。 OnAppearing();

VAR JSON =等待GetSalesPerProductAsync();

VAR salesPerProduct = JsonConvert.DeserializeObject<销售[]>(JSON);

modelForSales =新PlotModel
{
标题=销售每产品,
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TEXTCOLOR = OxyColors.White,
DefaultFont =宋体黑,
DefaultFontSize = 20

};

动态seriesP2 =新PieSeries将{StrokeThickness = 2.0,InsideLabelPosition = 0.8,AngleSpan = 360,由startAngle = 0};

的foreach(在salesPerProduct销售三)
{
seriesP2.Slices.Add(新PieSlice(c.PRODUCT_C​​ODE,c.PRODUCT_ID){IsExploded =假,填写= OxyColors。蒂尔});
}

modelForSales.Series.Add(seriesP2);
this.SalesPerProductModel = modelForSales;
}

公共PlotModel SalesPerProductModel {搞定;私人集; }

异步任务<串GT; GetSalesPerProductAsync()
{
VAR的客户=新的HttpClient();

client.BaseAddress =新的URI(http://192.168.1.11:50857/);

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));

HttpResponseMessage响应=等待client.GetAsync(API /销售);
如果(response.IsSuccessStatusCode)
{
返回等待response.Content.ReadAsStringAsync();
}
,否则返回response.ReasonPhrase;
}


}
}

Sales.cs

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;

命名空间XamarinFormsDemo.Models
{
公共类销售额
{
公众诠释标识{搞定;组; }
公众诠释ORDER_ID {搞定;组; }
公众诠释ORDER_DETAILS_ID {搞定;组; }
公众诠释PRODUCT_ID {搞定;组; }
公共字符串PRODUCT_C​​ODE {搞定;组; }
公共字符串NET_AMOUNT {搞定;组; }
}
}


解决方案

你在你的分配 PlotModel 来一个局部变量。你必须把它分配给你的视图模型。这是你的工作重构代码:



SalesPerProductPage.xaml:



 <?XML版本=1.0编码=UTF-8>?; 
< ContentPage的xmlns =htt​​p://xamarin.com/schemas/2014/forms
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2009/xaml
的xmlns:氧=CLR的命名空间:OxyPlot.Xamarin.Forms;装配= OxyPlot.Xamarin.Forms
的xmlns:地方=CLR的命名空间:App1的
X:类=App1的.SalesPerProductPage>

< ContentPage.Content>
<氧:PlotView模型={结合SalesPerProductModel}>< /氧:PlotView>
< /ContentPage.Content>

< / ContentPage>



SalesPerProductPage.xaml.cs:



 公共部分类SalesPerProductPage:ContentPage 
{
公共SalesPerProductViewModel viewModelforSales {搞定;组; }

公共SalesPerProductPage()
{
的InitializeComponent();

viewModelforSales =新SalesPerProductViewModel();
的BindingContext = viewModelforSales;
}

异步保护覆盖无效OnAppearing()
{
base.OnAppearing();

VAR JSON =等待GetSalesPerProductAsync();

VAR salesPerProduct = JsonConvert.DeserializeObject<销售[]>(JSON);

PlotModel modelForSales =新PlotModel
{
标题=销售每产品,
TitleColor = OxyColors.Teal,
TitleFontSize = 30,
TEXTCOLOR = OxyColors.White,
DefaultFont =宋体黑,
DefaultFontSize = 20

};

动态seriesP2 =新PieSeries将{StrokeThickness = 2.0,InsideLabelPosition = 0.8,AngleSpan = 360,由startAngle = 0,字号= 24};

的foreach(在salesPerProduct销售三)
{
seriesP2.Slices.Add(新PieSlice(c.PRODUCT_C​​ODE,c.PRODUCT_ID));
}

modelForSales.Series.Add(seriesP2);
viewModelforSales.SalesPerProductModel = modelForSales;
}

异步任务<串GT; GetSalesPerProductAsync()
{
VAR的客户=新的HttpClient();

client.BaseAddress =新的URI(http://10.0.0.17:64550/);

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));

HttpResponseMessage响应=等待client.GetAsync(API /销售);
如果(response.IsSuccessStatusCode)
{
返回等待response.Content.ReadAsStringAsync();
}
,否则返回response.ReasonPhrase;
}
}



SalesPerProductViewModel:

 公共类SalesPerProductViewModel:INotifyPropertyChanged的
{

公共事件PropertyChangedEventHandler的PropertyChanged =委托{};

私人PlotModel _salesPerProductModel;
公共PlotModel SalesPerProductModel
{
得到
{
返回_salesPerProductModel;
}

{
如果(!值= _salesPerProductModel)
{
_salesPerProductModel =价值;
的PropertyChanged(这一点,新PropertyChangedEventArgs(SalesPerProductModel));
}
}
}

公共SalesPerProductViewModel()
{
}
}


Good Day Everyone. I'm creating a Xamarin.Forms Portable Application. And I'm currently coding a PieChart (OxyPlot) that contains static data.

What I want to do is to have a Dynamic Data in every Pie Slice I have. Meaning, the data should come from my database.

I'm already able to retrieved data from my database and display it as a List in the Mobile Application that I'm creating using Web Api like this one :

ClientListPage.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"
             x:Class="XamarinFormsDemo.Views.ClientListPage"
             xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo"
             xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
             BackgroundImage="bg3.jpg"
             Title="Client List1">


<StackLayout>

  <SearchBar Placeholder="Search" Text="{Binding Keyword}" SearchCommand="{Binding SearchCommand}" x:Name="txtSearch" />

    <ListView ItemsSource="{Binding CustomerList, Mode=TwoWay}"
              HasUnevenRows="True"
              IsPullToRefreshEnabled="True"
              x:Name="listView">


      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <Grid Padding="10" RowSpacing="10" ColumnSpacing="5">
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
              </Grid.RowDefinitions>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
              </Grid.ColumnDefinitions>

              <controls:CircleImage Source="icon.png"
                     HeightRequest="66"
                     HorizontalOptions="CenterAndExpand"
                     Aspect="AspectFill"
                     WidthRequest="66"
                     Grid.RowSpan="2"
                   />




              <Label Grid.Column="1"
                     Text="{Binding CUSTOMER_NAME}"
                     TextColor="#24e97d"
                     FontSize="24"/>



              <Label Grid.Column="1"
                      Grid.Row="1"
                       Text="{Binding CUSTOMER_CODE}"
                       TextColor="White"
                       FontSize="18"
                       Opacity="0.6"/>


              <Label Grid.Column="1"
                  Grid.Row="2"
                  Text="{Binding CUSTOMER_MOBILE_NUMBER}"
                   TextColor="White"
                   FontSize="18"
                   Opacity="0.6"/>


              <Label Grid.Column="1"
                  Grid.Row="3"
                  Text="{Binding CUSTOMER_EMAIL_ADDRESS}"
                   TextColor="White"
                   FontSize="18"
                   Opacity="0.6"/>


            </Grid>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>

    </ListView>
</StackLayout>


</ContentPage>

ClientListPage.xaml.cs

using Newtonsoft.Json;
using OxyPlot;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using XamarinFormsDemo.ViewModels;



namespace XamarinFormsDemo.Views
{
    public partial class ClientListPage : ContentPage
    {

        CustomerVM viewModel;
        public ClientListPage()
        {
            NavigationPage.SetHasNavigationBar(this, true);


            InitializeComponent();
            viewModel = new CustomerVM();
            BindingContext = viewModel;
        }

        async override protected void OnAppearing()
        {
            base.OnAppearing();

            var json = await GetCustomerAsync();

            var customers = JsonConvert.DeserializeObject<Customer[]>(json);

            foreach (Customer c in customers)
                viewModel.CustomerList.Add(c);
        }

        async Task<string> GetCustomerAsync()
        {
            var client = new HttpClient();

            client.BaseAddress = new Uri("http://192.168.1.11:50857/");

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync("api/Customer");
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else return response.ReasonPhrase;
        }


    }
}

CustomerVM.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using XamarinFormsDemo.Services;
using XamarinFormsDemo.Views;


namespace XamarinFormsDemo.ViewModels
{
    public class CustomerVM : INotifyPropertyChanged
    {


        private ObservableCollection<Customer> _customerList; // keep all customers
        private ObservableCollection<Customer> _searchedCustomerList; // keep a copy for searching
        private Customer _selectedCustomer = new Customer();

        private string _keyword = "";
        public string Keyword
        {
            get
            {
                return _keyword;
            }
            set
            {
                this._keyword = value;

                // while keyword changed we filter Employees
                //Filter();
            }
        }




        public ObservableCollection<Customer> CustomerList
        {
            get
            {
                return _customerList;
            }
            set
            {
                _customerList = value;
                OnPropertyChanged();
            }
        }

        public CustomerVM()
        {
            CustomerList = new ObservableCollection<Customer>();
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}

But this time, I need to do it in a PieChart.

I really don't have an idea how to do this. But I think the way I retrieved the data from my WEB API above has similarity on how am I going to do this in my chart. Hope you can help me.

Thanks a lot. These are some of my codes :

SalesPerProductViewModel.cs

using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.Models;

namespace XamarinFormsDemo.ViewModels
{
    public class SalesPerProductViewModel : INotifyPropertyChanged
    {

        private ObservableCollection<Sales> _salesList; // keep all customers


        public ObservableCollection<Sales> SalesPerProductModel
        {
            get
            {
                return _salesList;
            }
            set
            {
                _salesList = value;
                OnPropertyChanged();
            }
        }

        public SalesPerProductViewModel()
        {

            SalesPerProductModel = new ObservableCollection<Sales>();


        }




        public event PropertyChangedEventHandler PropertyChanged;

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



    }
}

SalesPerProductPage.xaml (This is where the dynamic chart should be displayed)

<?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:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
             xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo"
             x:Class="XamarinFormsDemo.Views.SalesPerProductPage"
             BackgroundImage="bg3.jpg"
             Title="Sales Per Product">


  <ContentPage.BindingContext>
    <ViewModels:SalesPerProductViewModel/>
  </ContentPage.BindingContext>



  <Label Text="TOTAL SALES LABEL HERE!"
       TextColor="#24e97d"/>

    <oxy:PlotView Model="{Binding SalesPerProductModel}" />
</ContentPage>

SalesPerProductPage.xaml.cs

using OxyPlot;
using OxyPlot.Xamarin.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XamarinFormsDemo.ViewModels;
using Xamarin.Forms;
using XamarinFormsDemo.Models;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using OxyPlot.Series;

namespace XamarinFormsDemo.Views
{
    public partial class SalesPerProductPage : ContentPage
    {
        private PlotModel modelForSales;
        SalesPerProductViewModel viewModelforSales;

        public SalesPerProductPage()
        {
            InitializeComponent();
            viewModelforSales = new SalesPerProductViewModel();
            BindingContext = viewModelforSales;


        } //end of SalesPerProductPage()


        async override protected void OnAppearing()
        {
            base.OnAppearing();

            var json = await GetSalesPerProductAsync();

            var salesPerProduct = JsonConvert.DeserializeObject<Sales[]>(json);

            modelForSales = new PlotModel
            {
                Title = "Sales Per Product",
                TitleColor = OxyColors.Teal,
                TitleFontSize = 30,
                TextColor = OxyColors.White,
                DefaultFont = "Arial Black",
                DefaultFontSize = 20

            };

            dynamic seriesP2 = new PieSeries { StrokeThickness = 2.0, InsideLabelPosition = 0.8, AngleSpan = 360, StartAngle = 0 };

            foreach (Sales c in salesPerProduct)
            {
                seriesP2.Slices.Add(new PieSlice(c.PRODUCT_CODE, c.PRODUCT_ID) { IsExploded = false, Fill = OxyColors.Teal });
            }

            modelForSales.Series.Add(seriesP2);
            this.SalesPerProductModel = modelForSales;
        }

        public PlotModel SalesPerProductModel { get; private set; }

        async Task<string> GetSalesPerProductAsync()
        {
            var client = new HttpClient();

            client.BaseAddress = new Uri("http://192.168.1.11:50857/");

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync("api/Sales");
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else return response.ReasonPhrase;
        }


    }
}

Sales.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XamarinFormsDemo.Models
{
    public class Sales
    {
        public int Id { get; set; }
        public int ORDER_ID { get; set; }
        public int ORDER_DETAILS_ID { get; set; }
        public int PRODUCT_ID { get; set; }
        public string PRODUCT_CODE { get; set; }
        public string NET_AMOUNT { get; set; }
    }
}

解决方案

You're assigning your PlotModel to a local variable. You must assign it to your ViewModel. Here's your refactored working code:

SalesPerProductPage.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:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
             xmlns:local="clr-namespace:App1"
             x:Class="App1.SalesPerProductPage">

  <ContentPage.Content>
      <oxy:PlotView Model="{Binding SalesPerProductModel}"></oxy:PlotView>
  </ContentPage.Content>

</ContentPage>

SalesPerProductPage.xaml.cs:

public partial class SalesPerProductPage : ContentPage
{
    public SalesPerProductViewModel viewModelforSales { get; set; }

    public SalesPerProductPage()
    {
        InitializeComponent();

        viewModelforSales = new SalesPerProductViewModel();
        BindingContext = viewModelforSales;
    }

    async protected override void OnAppearing()
    {
        base.OnAppearing();

        var json = await GetSalesPerProductAsync();

        var salesPerProduct = JsonConvert.DeserializeObject<Sales[]>(json);

        PlotModel modelForSales = new PlotModel
        {
            Title = "Sales Per Product",
            TitleColor = OxyColors.Teal,
            TitleFontSize = 30,
            TextColor = OxyColors.White,
            DefaultFont = "Arial Black",
            DefaultFontSize = 20

        };

        dynamic seriesP2 = new PieSeries { StrokeThickness = 2.0, InsideLabelPosition = 0.8, AngleSpan = 360, StartAngle = 0, FontSize = 24 };

        foreach (Sales c in salesPerProduct)
        {
            seriesP2.Slices.Add(new PieSlice(c.PRODUCT_CODE, c.PRODUCT_ID));
        }

        modelForSales.Series.Add(seriesP2);
        viewModelforSales.SalesPerProductModel = modelForSales;
    }

    async Task<string> GetSalesPerProductAsync()
    {
        var client = new HttpClient();

        client.BaseAddress = new Uri("http://10.0.0.17:64550/");

        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await client.GetAsync("api/Sales");
        if (response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync();
        }
        else return response.ReasonPhrase;
    }
}

SalesPerProductViewModel:

public class SalesPerProductViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    private PlotModel _salesPerProductModel;
    public PlotModel SalesPerProductModel
    {
        get
        {
            return _salesPerProductModel;
        }
        set
        {
            if (value != _salesPerProductModel)
            {
                _salesPerProductModel = value;
                PropertyChanged(this, new PropertyChangedEventArgs("SalesPerProductModel"));
            }
        }
    }

    public SalesPerProductViewModel()
    {
    }
}

这篇关于Xamarin.Forms:如何填充一个饼图从网页API数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆