2013年1月29日火曜日

【WinRT】XAMLエディタでナゾのObject Null Reference

年末年始と特に問題なく進んできたので
ここに来るのも久しぶりである.
久しぶりに躓いた.
…とてつもなくしょうもないことなのだが.

WinRTでボタンをカスタムする.
表示と同時に別のクラスのイベントを登録し,
イベントが上がるごとにボタンの表示・非表示を変えたい.

適当にクラスを作ったが,OtherClassがイベント(EventOccurred)を上げてくると
OtherClass_EventOccurredメソッドが呼ばれ,
その中でViewChangeを呼び,ボタン自身の表示を切り替える.

つまり,イベントが起こるごとに表示/非表示を切り替えるボタンができた.

さて,このカスタムUIの使用方法は
XAMLエディタで
<local:CustomButton x:Name="playListButton" HorizontalAlignment="Right" />
このような感じである.
通常のButtonタグを
local:CustomButtonタグに変えただけだ.

しかしここで問題が起こる.

XAMLのlocal:CustomButtonタグの行に
Delegate to an instance method cannot have null 'this'.
もしくは
Object reference not set to an instance of an object
というエラーが発生する.

内容としては
インスタンスメソッドへのデリゲートにnullを指定できねえよ
とか
オブジェクトに何もセットされてねえよ
とかそういう意味だと思うが
それでもよく分からん.

しかし,ビルドすると通る.
配置もできて実行もされる.
すなわちランタイムでは問題が起きない.


ここで答え合わせ.

実はこのエラーは(多分)XAMLデザイナーが影響を受けたエラー.
ランタイムでは起きない.
VisualStudioのXAMLデザイナーでプレビューを表示させようとしたときに
OtherClass.Instanceというインスタンスが発見できず,
VisualStudio「おい,このインスタンスnullじゃねえか」
ということになってるんだと思う.

言ってしまえばUIコントロールに他のクラスのインスタンスを参照したのが原因.
XAMLデザイナーはそこまで見ずにプレビューを作成する.

しかし,実際にビルドすると通り,なおかつ動作に影響しないのは,
ランタイムではOtherClassクラスのインスタンスを生成しており,
CustomButtonクラスから参照できるからである.

実動作に問題がなければいいといえばいいのだが,
エラー一覧欄にWarningはもとより,Errorが表示されっぱなしというのは
精神衛生上よろしくない.

ここまで書くと解決法は簡単だと思うが,
このように変更するとエラー一覧欄から消えてくれる.


OtherClassのインスタンス,_instanceを参照する前に
それが存在するかどうか確認して,存在しなければreturnする処理を追加しただけ.

こういったリッチなエディタにはランタイムは問題なくデザイナーに起因するエラーというものが起こりがちである.
eclipse + Android SDKでもあるあるである.
UI周りでどっからどう考えてもおかしくないのにエラーが消えないという場合は
このようにデザイナーを疑ってみるのもいいかもしれない.

0 件のコメント:

コメントを投稿