Xamarin.Forms:使用OxyPlot创建图表时出错

本文关键字:出错 创建 OxyPlot Forms 使用 Xamarin | 更新日期: 2023-09-27 17:57:48

大家好。我正在创建一个Xamarin.Forms(可移植)应用程序,我想使用OxyPlot创建一个图表。我尝试过这个代码,但它有一个错误,指向我的LoadApplication(new App())MainActivity.cs在我的Xamarin.Android部分中声明

"System.NullReferenceException:对象引用未设置为对象的实例"

你认为这背后的原因是什么?

以下是我的一些代码:

SalesPage.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.SalesPage"
         xmlns:oxy="clr-namespace:OxyPlot.XamarinForms;assembly=OxyPlot.XamarinForms"
         BackgroundImage="bg3.jpg"
         Title="Sales Page">
 <StackLayout>
   <oxy:PlotView Model="{Binding OxyPlotModel}" VerticalOptions="Center" HorizontalOptions="Center" />
</StackLayout>
</ContentPage>

SalesPage.xaml

using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;   
using Xamarin.Forms;
namespace XamarinFormsDemo.Views
{
    public partial class SalesPage 
    {

    public SalesPage()
    {
        InitializeComponent();
        var plotModel = new PlotModel { Title = "OxyPlot Demo" };
        plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
        plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Maximum = 10, Minimum = 0 });
        var series1 = new LineSeries
        {
            MarkerType = OxyPlot.MarkerType.Circle,
            MarkerSize = 4,
            MarkerStroke = OxyPlot.OxyColors.White
        };
        series1.Points.Add(new DataPoint(0.0, 6.0));
        series1.Points.Add(new DataPoint(1.4, 2.1));
        series1.Points.Add(new DataPoint(2.0, 4.2));
        series1.Points.Add(new DataPoint(3.3, 2.3));
        series1.Points.Add(new DataPoint(4.7, 7.4));
        series1.Points.Add(new DataPoint(6.0, 6.2));
        series1.Points.Add(new DataPoint(8.9, 8.9));
        plotModel.Series.Add(series1);
        }
    }
}

MainActivity.cs

using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

using ImageCircle.Forms.Plugin.Droid;
namespace XamarinFormsDemo.Droid
{
    [Activity(Label = "XamarinFormsDemo", Icon = "@drawable/recordsicon",     MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize |     ConfigChanges.Orientation)]
    public class MainActivity :     global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
        base.OnCreate(bundle);
        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());
        OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();
       ImageCircleRenderer.Init();
        }
    }
}

Xamarin.Forms:使用OxyPlot创建图表时出错

您不会在任何位置为页面设置DataContext。至少在您显示的代码中没有。因此,绑定到似乎也不存在的OxyPlotModel属性将不起作用。

如果你只想在页面中查看你制作的模型,那么只需将其分配给PlotView,如下所示:

  1. 将名称属性添加到绘图视图中。x:Name="Graph"
  2. 只需将创建的PlotModel指定给Graph:Graph.Model = plotModel的Model属性即可

但是,您可能需要在OnAppearing覆盖中执行此操作,因此您的代码可能需要在该方法中下移,如:

public override void OnAppearing()
{
    var plotModel = new PlotModel { Title = "OxyPlot Demo" };
    plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
    plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Maximum = 10, Minimum = 0 });
    var series1 = new LineSeries
    {
        MarkerType = OxyPlot.MarkerType.Circle,
        MarkerSize = 4,
        MarkerStroke = OxyPlot.OxyColors.White
    };
    series1.Points.Add(new DataPoint(0.0, 6.0));
    series1.Points.Add(new DataPoint(1.4, 2.1));
    series1.Points.Add(new DataPoint(2.0, 4.2));
    series1.Points.Add(new DataPoint(3.3, 2.3));
    series1.Points.Add(new DataPoint(4.7, 7.4));
    series1.Points.Add(new DataPoint(6.0, 6.2));
    series1.Points.Add(new DataPoint(8.9, 8.9));
    plotModel.Series.Add(series1);
    Graph.Model = plotModel;
}

一个更好的方法是利用MVVM模式,通过创建这样的ViewModel:

public class SalesViewModel : INotifyPropertyChanged
{
    private PlotModel _plotModel;
    public PlotModel PlotModel
    {
        get { return _plotModel; }
        set {
            _plotModel = value;
            RaisePropertyChanged();
        }
    }
    // other methods here that create your model
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler (this, new PropertyChangedEventArgs (propertyName));
    }
}

然后,您可以在某个地方实例化ViewModel,可能是在OnAppearing()中,并将其设置为BindingContext:

public override void OnAppearing()
{
    var viewModel = new SalesViewModel();
    this.BindingContext = viewModel;
}

然后你可以使用你在页面中创建的绑定:

<?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.SalesPage"
    xmlns:oxy="clr-namespace:OxyPlot.XamarinForms;assembly=OxyPlot.XamarinForms"
    BackgroundImage="bg3.jpg"
    Title="Sales Page">
    <StackLayout>
        <oxy:PlotView Model="{Binding PlotModel}" VerticalOptions="Center" HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

请记住,每次更改PlotModel时都要在其上调用RaisePropertyChanged()以使其反映在视图中:RaisePropertyChanged("PlotModel");