这是一个有趣的小问题。如果您深入了解变量MyLineSeries 的创建和分配方式,将会有所帮助。导航到InitializeComponent 方法的定义。您最终会看到 MainPage.g.cs 生成的文件。它将包含此字段:-
internal System.Windows.Controls.DataVisualization.Charting.LineSeries MyLineSeries;
在InitializeComponent 中你会发现这一行:-
this.MyLineSeries = ((System.Windows.Controls.DataVisualization.Charting.LineSeries)(this.FindName("MyLineSeries")));
所以表面上看,当你的构造函数中对InitializeComponent 的调用完成时,MyLineSeries 应该已经被赋值了。但是,您可以看到它仍然为空,因此可以得出结论,FindName("MyLineSeries") 未能找到该系列。那么问题来了,为什么会失败?
为什么 FindName 不起作用?
FindName 搜索文档中称为“对象树”的内容,寻找具有指定名称的对象(所谓的名称范围会增加复杂性,但在这里没有发挥作用)。通常,对象通过常见的基本类型(如Panel 或ContentControl)最终进入“对象树”,这些基本类型分别具有Children 和Child 等属性。这些属性在类的ContentProperty 属性中指定,从而可以更自然地描述 UI 结构。例如:-
<Button x:Name="MyButton">
<Image x:Name="MyImage" ... />
</Button>
代替
<Button x:Name="MyButton">
<Button.Child>
<Image x:Name="MyImage" ... />
</Button.Child>
</Button>
另一方面,Chart 控件不是简单的Panel 派生类,在构建其 UI 方面还有很多工作要做。对于Chart,ContentPropertyAttribute 指定Series 集合参数。这允许您更自然的 Xaml:-
<Charting:Chart Title="Chart to test" Name="MySuperChart">
<Charting:LineSeries x:Name="MyLineSeries" Title="Something" />
</Charting:Chart>
但是,因为Chart 有很多额外的工作来确定“对象树”中究竟应该是什么来代表其最终 UI,所以系列集合项目不会立即成为“对象树”的一部分.结果InitializeComponent 中的FindName 根本找不到它们。
解决方法 - 选项 1
您可以使用您对图表中“MyLineSeries”序数位置的了解来处理构造函数中MyLineSeries 变量的分配。从 Xaml 中删除 x:Name="MyLineSeries" 然后在代码中:-
public partial MainPage : UserControl
{
private LineSeries MyLineSeries;
public MainPage()
{
InitializeComponent();
MyLineSeries = (LineSeries)MySuperChart.Series[0];
}
}
解决方法 - 选项 2
您可以等到该系列在“对象树”中可用,一旦包含的UserControl 触发了它的Loaded 事件,这是真的:-
public partial MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Loaded += (s, args) =>
{
MyLineSeries = (LineSeries)FindName("MyLineSeries");
}
}
}