これは興味深い小さな落とし穴です。変数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")
ただし、まだ null であることがわかるため、シリーズを見つけることができなかったと結論付けることができます。問題は、なぜ失敗したのかということです。
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
の場合はコレクションパラメータをContentPropertyAttribute
指定します。Series
これにより、より自然な Xaml が可能になります。
<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");
}
}
}