这是一个有趣的小问题。如果您稍微了解一下变量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
的情况下。这允许您更自然的 Xaml:-ContentPropertyAttribute
Series
<Charting:Chart Title="Chart to test" Name="MySuperChart">
<Charting:LineSeries x:Name="MyLineSeries" Title="Something" />
</Charting:Chart>
然而,由于Chart
需要做很多额外的工作才能确定“对象树”中将代表其最终 UI 的确切内容,因此系列集合项目不会立即成为“对象树”的一部分。结果根本找不到它们FindName
。InitializeComponent
解决方法 - 选项 1
您可以使用您对图表中“MyLineSeries”序数位置的了解来处理MyLineSeries
构造函数中变量的分配。x:Name="MyLineSeries"
从 Xaml 中删除,然后在代码中:-
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");
}
}
}