为什么我的2个Livecharts笛卡尔实例不起作用



我当前的代码有问题。

基本上,我需要在应用程序的一个网格中显示2个图,但它似乎不起作用。问题是会显示一张图,而第二张图不会绘制该图。

以下是使用的代码:

XAML:

<Grid>
<lvc:CartesianChart x:Name="cartchartdb" Series="{Binding SeriesCollection}" LegendLocation="Right" Margin="10,249,578.4,218.2" >
<lvc:CartesianChart.AxisY>
<lvc:Axis Title="Average Gap (Meter)" LabelFormatter="{Binding YFormatter}"></lvc:Axis>
</lvc:CartesianChart.AxisY>
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="Time" Labels="{Binding Labels}"></lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Grid>
<Grid>
<lvc:CartesianChart Series="{Binding SeriesCollection2}" LegendLocation="Right" Margin="792,160,9.8,238" >
<lvc:CartesianChart.AxisY>
<lvc:Axis Title="Sales" LabelFormatter="{Binding YFormatter2}"></lvc:Axis>
</lvc:CartesianChart.AxisY>
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="Month" Labels="{Binding Labels2}"></lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Grid>

C#:

public MainWindow(){
cartchartinit();
cartchartinit2();
}
private void cartchartinit2()
{
SeriesCollection2 = new SeriesCollection
{
new LineSeries
{
Title = "Series 1",
Values = new ChartValues<double> { 4, 6, 5, 2 ,7 }
},
new LineSeries
{
Title = "Series 2",
Values = new ChartValues<double> { 6, 7, 3, 4 ,6 }
}
};
Labels2 = new[] { "Jan", "Feb", "Mar", "Apr", "May" };
YFormatter2 = value => value.ToString("C");
//modifying the series collection will animate and update the chart
SeriesCollection2.Add(new LineSeries
{
Values = new ChartValues<double> { 5, 3, 2, 4 },
LineSmoothness = 0 //straight lines, 1 really smooth lines
});
//modifying any series values will also animate and update the chart
SeriesCollection2[2].Values.Add(5d);
DataContext = this;
}
public SeriesCollection SeriesCollection2 { get; set; }
public string[] Labels2 { get; set; }
public Func<double, string> YFormatter2 { get; set; }
private void cartchartinit()
{
SeriesCollection = new SeriesCollection
{
new LineSeries
{
Title = "Average Vehicles Gap",
Values = null
},
/* new LineSeries
{
Title = "Avg Gap (Metre)",
Values = null

},*/
/*new LineSeries
{
Title = "Series 3",
Values = new ChartValues<double> { 4,2,7,2,7 },
PointGeometry = DefaultGeometries.Square,
PointGeometrySize = 15
}*/
};
Labels = null;
YFormatter = value => value.ToString("");

DataContext = this;
}
public SeriesCollection SeriesCollection { get; set; }
public string[] Labels { get; set; }
public Func<double, string> YFormatter { get; set; }

当我只使用cartchartinit((方法时,它是有效的。但是当我添加cartchartinit2((时,它只为后面的图表绘制图形。我做错了吗?

如有帮助,不胜感激。

谢谢

第一个图表为空,因为绑定源也是
您对SeriesCollection属性的初始化进行了注释,并将唯一系列项目的LineSeries.Values属性设置为null==>此处没有要显示的数据集。您还遇到了未向绑定引擎报告属性更改的问题。

您的代码有几个问题。解决最重要的问题:

布局

不要将每个控件包装成Grid
这只会增加渲染性能成本。包装网格是绝对多余的。Grid是布局Panel,但目前您没有将其用于元素排列。

不要使用Margin来定位网格
这不允许您的应用程序进行扩展,而且基于边距的布局很难实现
如果您需要绝对定位,请使用Canvas。如果需要相对定位,请使用类似GridPanel,例如用于基于列和行的布局,或者使用StackPanel用于简单的垂直或水平排列元素。

仅对Margin进行小的调整,最好是对其相对屏幕位置进行调整。

从页边空白处看,您希望图表显示为两行两列(从左上角到右下角的对角线(。在这种情况下,使用Grid:

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<lvc:CartesianChart Grid.Row="0" Grid.Column="0"
Series="{Binding SeriesCollection}" 
LegendLocation="Right">
...
</lvc:CartesianChart>
<lvc:CartesianChart Grid.Row="1" Grid.Column="1"
Series="{Binding SeriesCollection2}" 
LegendLocation="Right">
...
</lvc:CartesianChart>
</Grid>

如果您想将图表并排对齐,只需使用StackPanel:

<StackPanel Orientation="Horizontal">    
<lvc:CartesianChart Series="{Binding SeriesCollection}" 
LegendLocation="Right">
...
</lvc:CartesianChart>
<lvc:CartesianChart Series="{Binding SeriesCollection2}" 
LegendLocation="Right">
...
</lvc:CartesianChart>
</StackPanel>

数据绑定

您可以使用数据绑定将图表数据分配给图表。这很好。但是您是在初始化XAML绑定表达式之后设置绑定源的。由于所有源属性(例如SeriesCollectionSeriesCollection2(既不是DependencyProperty,也不是引发INotifyPropertyChanged.PropertyChanged事件,因此绑定引擎不会获取这些属性的更改/分配。在您的情况下,它是有效的,但这只是因为您在刷新Binding.Source,在每次属性更改后重新分配this.DataContext = this
这将强制视图中的每个绑定重新初始化。

在更复杂的应用程序中,这将显著增加启动时间或导致UI迟钝
WPF默认继承视觉树下的DataContext属性值(例外,例如DataTemplate(:每个子元素隐式共享其父元素的相同DataContext
这意味着刷新此属性会影响整个视觉树==>不要因为Binding.Path更新了就刷新Binding.Source(尤其是DataContext(。

让绑定引擎处理这些更改:

每当绑定的源属性预期动态更改时,源对象必须将这些属性实现为DependencyProperty,或者如果此对象不是DependencyObject,则必须实现INotifyPropertyChanged

请参阅WPF中的数据绑定概述和依赖属性概述

WindowDependencyObject,因此MainWindow应将用作绑定源或绑定目标的所有属性实现为DependencyProerty:

partial class MainWindow : Window
{
public static readonly DependencyProperty SeriesCollectionProperty = DependencyProperty.Register(
"SeriesCollection",
typeof(SeriesCollection),
typeof(MainWindow),
new PropertyMetadata(default(SeriesCollection)));
public SeriesCollection SeriesCollection
{
get => (SeriesCollection) GetValue(MainWindow.SeriesCollectionProperty);
set => SetValue(MainWindow.SeriesCollectionProperty, value);
}
public static readonly DependencyProperty SeriesCollection2Property = DependencyProperty.Register(
"SeriesCollection2",
typeof(SeriesCollection),
typeof(MainWindow),
new PropertyMetadata(default(SeriesCollection)));
public SeriesCollection SeriesCollection2
{
get => (SeriesCollection) GetValue(MainWindow.SeriesCollection2Property);
set => SetValue(MainWindow.SeriesCollection2Property, value);
}
... // Do this for all properties that serve as binding source or target
public MainwWindow()
{
InitializeComponent();
this.DataContext = this;
}
private void cartchartinit()
{
// Aside from their slightly clumsy definition, 
// dependency properties are used like common CLR properties
SeriesCollection = new SeriesCollection();
}
}

相关内容

  • 没有找到相关文章

最新更新