LiveCharts的SeriesCollection不显示在CartesianChart上

3

在修改了网站文档提供的代码后,我无法正常显示SeriesCollection。让我展示一下我所做的。

首先是XAML:

<Grid>
    <lvc:CartesianChart Series="{Binding GraphData.SeriesCollection}"
                    LegendLocation="Top">
        <lvc:CartesianChart.AxisY>
            <lvc:Axis Title="VIs"></lvc:Axis>
        </lvc:CartesianChart.AxisY>
        <lvc:CartesianChart.AxisX>
            <lvc:Axis Title="Players"></lvc:Axis>
        </lvc:CartesianChart.AxisX>
    </lvc:CartesianChart>
</Grid>

在我的ViewModel中,我有一个自定义对象存储了我希望绑定到这个图表上的信息:
public GraphModel GraphData { get; set; } = new GraphModel();

我有一个按钮来测试我的代码。单击它会执行以下代码:

private void UpdateGraphStatistics()
{
    var compdata = new List<double>();
    var dqdata = new List<double>();

    foreach (var item in Competitors)
    {
        if (!item.DQ)
        {
            compdata.Add(item.VIs);
        }
        else if (item.DQ)
        {
            dqdata.Add(item.VIs);
        }
    }

    GraphData = new GraphModel(compdata, dqdata);
}

就所有目的而言,以上代码将一系列double值添加到两个列表中,我已确定这部分是有效的(因此这不是问题;SeriesCollection不为空!)

接下来是GraphModel。这是一个大问题,问题可能出在这里,但我无法确定原因:

class GraphModel
{
    public ChartValues<ObservablePoint> CompetitionData = new ChartValues<ObservablePoint>();
    public ChartValues<ObservablePoint> DQData = new ChartValues<ObservablePoint>();
    public SeriesCollection SeriesCollection { get; set; }

    public GraphModel()
    {
        CreateSeriesCollection();
    }

    public GraphModel(List<double> competitionData, List<double> dqData)
    {
        ParseData(competitionData, dqData);

        CreateSeriesCollection();
    }

    private void CreateSeriesCollection()
    {
        SeriesCollection = new SeriesCollection
        {
            new LineSeries
            {
                Title = "Competition Data (VIs/Player Number)",
                Values = CompetitionData,
                LineSmoothness = 0.6,
                PointForeground = Brushes.Blue
            },
            new LineSeries
            {
                Title = "DQ Data (VIs/Player Number)",
                Values = DQData,
                LineSmoothness = 1,
                PointForeground = Brushes.Red
            }
        };
    }

    private void ParseData(List<double> compData, List<double> dqData)
    {
        // Convert competitionData into observable points
        int count = 1;
        foreach (var item in compData)
        {
            CompetitionData.Add(new ObservablePoint(count++, item));
        }


        // Convert dqdata into observable points
        int offsetX = CompetitionData.Count;
        foreach (var item in dqData)
        {
            DQData.Add(new ObservablePoint(offsetX++, item));
        }
    }
}

之前在非WPF代码中已经使用过ParseData()方法,因此我知道这不太可能是问题的原因。

我仍然没有解决问题。难道我的数据绑定方式不正确吗?

编辑

为了更好地理解,我知道GraphModel中的SeriesCollection肯定包含我想要的信息,因为这段代码与我最初试用的非WPF版本的软件基本相同。


这只是一个猜测,可能与LiveCharts的SeriesCollection没有实现INotifyCollectionChanged有关吗? - BenderBoy
1
@BenderBoy 哦!我忘了我其实自己解决了这个问题。事实证明,每次想要更新图形时,我都犯了一个错误,那就是创建一个新的对象,这反过来又移除了视图对此的绑定。我通过在类中实现一种方法来改变SeriesCollection的值,从而解决了这个问题,给出新数据。另一种选择是重新绑定数据,但我认为这是合适的解决方案!我很快会发布代码作为答案! - TimeTravelPenguin
1个回答

1
我解决了自己的问题。问题在于每次我想要更新图表数据时都运行相同的方法(如上所示):
private void UpdateGraphStatistics()
{
    var compdata = new List<double>();
    var dqdata = new List<double>();

    foreach (var item in Competitors)
    {
        if (!item.DQ)
        {
            compdata.Add(item.VIs);
        }
        else if (item.DQ)
        {
            dqdata.Add(item.VIs);
        }
    }

    GraphData = new GraphModel(compdata, dqdata);
}

这段代码的问题在于它创建了一个新对象,实际上断开了视图与GraphData之间的绑定。
我面临两个选择:不创建新对象,或者创建新对象然后重新绑定视图到该对象。
因为我还没有找到如何优雅地重新绑定视图的方法,所以我选择创建一个对象内部的方法来修改数据。我做了以下操作:
public void ParseData(List<CompetitorModel> compData, List<CompetitorModel> dqData)
{
    CompetitionData.Clear();
    DQData.Clear();

    // Convert competitionData into observable points
    int count = 0;
    foreach (var item in compData)
    {
        CompetitionData.Add(new ObservablePoint(count++, item.VIs));
    }


    // Convert dqdata into observable points
    int offsetX = compData.Count;
    foreach (var item in dqData)
    {
        DQData.Add(new ObservablePoint(offsetX++, item.VIs));
    }
}

简而言之,我将处理数据解析的代码部分设置为公共对象,这会清除其中的集合,并且通过修改 CompetitionData 和 DQData 集合来 构建新的 修改现有的 SeriesCollection,仍然绑定到视图,而不会破坏绑定关系。一旦我学会重新绑定数据,我就可以将此方法设置为私有并简单地创建一个新对象,但是每次都要创建整个 SeriesCollection(以及现在模型中的其他 Func 和内容),因此从理论上讲,此方法可能更快速。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接