Это интересный маленький гоча. Помогает, если вы немного загляните за пределы того, как переменная 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
в классах, что позволяет более естественно описать структуру пользовательского интерфейса. 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
и имеет гораздо больше работы для создания своего пользовательского интерфейса. В случае 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
в конструкторе. Удалите 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");
}
}
}