This is an interesting little booty. This helps if you are a little under the hood watching how the MyLineSeries variable is created and assigned. Go to the definition of the InitializeComponent method. You will be taken to the file generated by MainPage.g.cs. It will contain this field: -
internal System.Windows.Controls.DataVisualization.Charting.LineSeries MyLineSeries;
and in InitializeComponent you will find this line: -
this.MyLineSeries = ((System.Windows.Controls.DataVisualization.Charting.LineSeries)(this.FindName("MyLineSeries")));
Thus, by the time it finishes calling InitializeComponent , a MyLineSeries should be assigned in your MyLineSeries constructor. However, since you can see it is still null, therefore, we can conclude that FindName("MyLineSeries") could not find the series. So the question is, why didnβt it pass?
Why does FindName not work?
FindName searches for what is referred to in the documentation as an βobject treeβ, looking for an object with the specified name (complications of so-called name copies are added, but this does not play here). Typically, objects appear in the "object tree" through common base types, such as Panel or ContentControl , which have values ββsuch as Children and Child respectively. These properties are specified in the ContentProperty attribute for classes, which allow a more natural description of the user interface structure. For instance: -.
<Button x:Name="MyButton"> <Image x:Name="MyImage" ... /> </Button>
Instead
<Button x:Name="MyButton"> <Button.Child> <Image x:Name="MyImage" ... /> </Button.Child> </Button>
The Chart control, on the other hand, is not a simple derivative of the Panel and has much more work to create its user interface. In the case of Chart the ContentPropertyAttribute parameter specifies the Series collection parameter. This allows your more natural Haml: -
<Charting:Chart Title="Chart to test" Name="MySuperChart"> <Charting:LineSeries x:Name="MyLineSeries" Title="Something" /> </Charting:Chart>
However, since Chart has a lot of additional work to determine what exactly should be in the "tree of objects" that will represent its final interface, the elements of the series collection do not immediately become part of the "tree of objects". As a result, FindName in the InitializeComponent simply does not find them .
Work Around - Option 1
You can use your knowledge of the "MyLineSeries" ordinal position in the chart to handle the MyLineSeries variable MyLineSeries in the constructor. Remove x:Name="MyLineSeries" from Xaml, then in code: -
public partial MainPage : UserControl { private LineSeries MyLineSeries; public MainPage() { InitializeComponent(); MyLineSeries = (LineSeries)MySuperChart.Series[0]; } }
Work Around - Option 2
You can wait until the series is available in the "object tree", which is true if the containing UserControl triggered the Loaded event: -
public partial MainPage : UserControl { public MainPage() { InitializeComponent(); Loaded += (s, args) => { MyLineSeries = (LineSeries)FindName("MyLineSeries"); } } }