为什么图表没有更新
Why is the chart not updating
我正在使用 C# 库 LiveCharts.wpf 的 CartesianChart 在 wpf 应用程序中制作图表。图表应该实时更新,我不明白为什么它不起作用。
这是我的简单主程序window,它构成了一个 Graderview
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="13*" x:Name="LeftColoumn"/>
<ColumnDefinition Width="12*" x:Name="RightColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="12*" x:Name="UpperRow"/>
<RowDefinition Height="12*" x:Name="LowerRow"/>
</Grid.RowDefinitions>
<local:GraderView Grid.ColumnSpan="1">
</local:GraderView>
</Grid>
这是 wpf 用户控件 graderView.cs。在构造函数中,它异步启动模拟。随着此模拟的进行,只要有新值可用,就会调用事件处理程序 OnUpdateChartView。
public partial class GraderView : UserControl
{
public ChartValues<int> GraderOutputCount { get; set; }
public string[] GraderLabels { get; set; }
public Grader Grader { get; set; }
public GraderView()
{
InitializeComponent();
GraderOutputCount = new ChartValues<int>() { 1, 2, 3 };
GraderLabels = new string[20];
Simulator simulator = new Simulator();
simulator.Simulate();
Grader = simulator.Grader;
Grader.UpdateChartView += OnUpdateChartView;
DataContext = this;
}
//Event handler
void OnUpdateChartView(object sender, EventArgs e)
{
Trace.WriteLine("OnUpdateChartView got called");
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
GraderLabels = Grader.SortedOutputConveyors.Select(x => x.Item1).ToArray();
for (int i = 0; i < GraderLabels.Length; i++)
{
Trace.WriteLine($"label:{GraderLabels[i]} amount:{GraderOutputCount[i]}");
}
}
}
由于 Trace.Writelines,我能够验证当应用 运行 时事件处理程序确实被调用。这是例如输出 window:
中出现的内容
OnUpdateChartView got called
label:9,5 - 10,5 amount:4
label:8,5 - 9,5 amount:7
label:7,5 - 8,5 amount:9
label:6,5 - 7,5 amount:10
label:5,5 - 6,5 amount:7
label:4,5 - 5,5 amount:8
label:3,5 - 4,5 amount:7
label:2,5 - 3,5 amount:8
label:1,5 - 2,5 amount:7
label:0,5 - 1,5 amount:6
这是此 WPF 用户控件 GraderView 的 xaml。绑定对我来说是正确的。 GraderOutputCount 的值和 GraderLabels 的标签。
<UserControl x:Class="WpfApp1.GraderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance local:GraderView}">
<Grid>
<lvc:CartesianChart>
<lvc:CartesianChart.Series>
<lvc:ColumnSeries Title="Grader" Values="{Binding GraderOutputCount}"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="WeightClass" Labels="{Binding GraderLabels}"/>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis Title="BoxCount" />
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
我的预期结果是首先获得我放入 GraderView 的构造函数中的 1、2、3,然后随着模拟的进行,图表将自动更新为 GraderOutputCount 和 Graderlabels 中的较新值。这不是实际发生的事情。图表根本不更新。谁能告诉我我在这里做错了什么?提前致谢
What it looks like
我找到问题发生的原因了。
我变了
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
至
GraderOutputCount.Clear();
foreach(var num in Grader.SortedOutputConveyors.Select(x => x.Item2.Count))
{
GraderOutputCount.Add(num);
}
我正在使用 C# 库 LiveCharts.wpf 的 CartesianChart 在 wpf 应用程序中制作图表。图表应该实时更新,我不明白为什么它不起作用。
这是我的简单主程序window,它构成了一个 Graderview
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="13*" x:Name="LeftColoumn"/>
<ColumnDefinition Width="12*" x:Name="RightColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="12*" x:Name="UpperRow"/>
<RowDefinition Height="12*" x:Name="LowerRow"/>
</Grid.RowDefinitions>
<local:GraderView Grid.ColumnSpan="1">
</local:GraderView>
</Grid>
这是 wpf 用户控件 graderView.cs。在构造函数中,它异步启动模拟。随着此模拟的进行,只要有新值可用,就会调用事件处理程序 OnUpdateChartView。
public partial class GraderView : UserControl
{
public ChartValues<int> GraderOutputCount { get; set; }
public string[] GraderLabels { get; set; }
public Grader Grader { get; set; }
public GraderView()
{
InitializeComponent();
GraderOutputCount = new ChartValues<int>() { 1, 2, 3 };
GraderLabels = new string[20];
Simulator simulator = new Simulator();
simulator.Simulate();
Grader = simulator.Grader;
Grader.UpdateChartView += OnUpdateChartView;
DataContext = this;
}
//Event handler
void OnUpdateChartView(object sender, EventArgs e)
{
Trace.WriteLine("OnUpdateChartView got called");
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
GraderLabels = Grader.SortedOutputConveyors.Select(x => x.Item1).ToArray();
for (int i = 0; i < GraderLabels.Length; i++)
{
Trace.WriteLine($"label:{GraderLabels[i]} amount:{GraderOutputCount[i]}");
}
}
}
由于 Trace.Writelines,我能够验证当应用 运行 时事件处理程序确实被调用。这是例如输出 window:
中出现的内容OnUpdateChartView got called
label:9,5 - 10,5 amount:4
label:8,5 - 9,5 amount:7
label:7,5 - 8,5 amount:9
label:6,5 - 7,5 amount:10
label:5,5 - 6,5 amount:7
label:4,5 - 5,5 amount:8
label:3,5 - 4,5 amount:7
label:2,5 - 3,5 amount:8
label:1,5 - 2,5 amount:7
label:0,5 - 1,5 amount:6
这是此 WPF 用户控件 GraderView 的 xaml。绑定对我来说是正确的。 GraderOutputCount 的值和 GraderLabels 的标签。
<UserControl x:Class="WpfApp1.GraderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance local:GraderView}">
<Grid>
<lvc:CartesianChart>
<lvc:CartesianChart.Series>
<lvc:ColumnSeries Title="Grader" Values="{Binding GraderOutputCount}"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="WeightClass" Labels="{Binding GraderLabels}"/>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis Title="BoxCount" />
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
我的预期结果是首先获得我放入 GraderView 的构造函数中的 1、2、3,然后随着模拟的进行,图表将自动更新为 GraderOutputCount 和 Graderlabels 中的较新值。这不是实际发生的事情。图表根本不更新。谁能告诉我我在这里做错了什么?提前致谢
What it looks like
我找到问题发生的原因了。 我变了
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
至
GraderOutputCount.Clear();
foreach(var num in Grader.SortedOutputConveyors.Select(x => x.Item2.Count))
{
GraderOutputCount.Add(num);
}