Silverlight 4工具包,charting和lineSeries为null

时间:2010-05-02 13:17:04

标签: silverlight charts silverlight-toolkit

我使用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

1 个答案:

答案 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在文档中搜索“对象树”中所指的内容,查找具有指定名称的对象(添加了名称范围内的并发症但在此处不起作用) )。通常,对象通过诸如PanelContentControl之类的公共基本类型最终位于“对象树”中,这些类型分别具有ChildrenChild等属性。这些属性在类的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");
    }
  }
}