我使用Silverlight 4工具包创建了Silverlight图表,即4月发布。
考虑以下图表:
<Grid x:Name="LayoutRoot" Background="White">
<Charting:Chart Title="Chart to test" Name="MySuperChart">
<Charting:LineSeries x:Name="MyLineSeries" Title="Something" />
</Charting:Chart>
</Grid>
到目前为止一切顺利。我可以通过MySuperChart.Series[0]
访问图表中的系列但是当我尝试引用MyLineSeries时,它似乎是空的。
picture http://i41.tinypic.com/9k4h7t.png
Full view
答案 0 :(得分:6)
这是一个有趣的小问题。如果你看一下如何创建和分配变量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
分配了一个值。但是你可以看到它仍然是null,因此可以得出结论FindName("MyLineSeries")
未能找到该系列。所以问题是它为什么失败了?
为什么FindName不起作用?
FindName
在文档中搜索“对象树”中所指的内容,查找具有指定名称的对象(添加了名称范围内的并发症但在此处不起作用) )。通常,对象通过诸如Panel
或ContentControl
之类的公共基本类型最终位于“对象树”中,这些类型分别具有Children
和Child
等属性。这些属性在类的ContentProperty
属性中指定,允许更自然地描述UI结构。 E.g: -
<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
有很多额外的工作要确定在“对象树”中应该是什么,它将代表它的最终用户界面,系列集合项不会立即成为“对象”的一部分树”。因此,FindName
中的InitializeComponent
根本找不到它们。
解决方法 - 选项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");
}
}
}