最近作ったとあるカスタム コントロールを Windows Form に貼ったときに、なぜか Windows Form の Localizable プロパティを操作できなくなっていました。現象は以下の通り。
- Localizable プロパティを操作したときに「プロパティの値が無効です」ダイアログが出る。
- そのダイアログの詳細には「オブジェクト参照がオブジェクト インスタンスに設定されていません。」と出る。
- Localizable プロパティの値が True から False に変わる場合でも、False から True に変わる場合でも現象は同じ。
- 件のカスタムコントロールを外せば、Localizable プロパティを操作できる。
- この現象が起きているとき、ビルドした際にはローカライズ済みリソースが出力されない。(もちろん Localizable プロパティが True になっている。)
- カスタムコントロール内には null ポインタを逆参照しているようなプロパティもない。(そんなのあったら、Localizable 云々の前に発見できるはず。)
ところで。
Localizable プロパティはどこにある?
このデバッグしているときに、今更気付いたのですが、System.Windows.Forms.Form.Localizable なんてプロパティは存在しません。デバッグのためにコード上で Localizable プロパティを操作しようと思ったのですが、そんなものありませんでした。Localizable プロパティと Language プロパティは、は、System.ComponentModel.Design.Serialization.CodeDomLocalizationProvider 拡張プロバイダによって提供されるプロパティでありました。
(拡張プロバイダによって追加されるプロパティで有名なのは、ToolTip のプロパティかな。)
さてさて。
何が悪さをしていたのか?
答えは、カスタム コントロールに設定していた、カスタムのデザイナ内のとあるイベントハンドラ。
いうか、これ→「方法 : デザイン モードでコントロールの外観と動作を拡張する」のサンプルソース内の「changeService_ComponentChanged()」メソッド(ページ内検索してくださいね)。
void changeService_ComponentChanged(object sender, ComponentChangedEventArgs e)
{
if (object.ReferenceEquals(
e.Component,
this.relatedControl))
{
if (e.Member.Name == "Margin" ||
e.Member.Name == "Padding" )
{
this.marginAndPaddingAdorner.Invalidate();
}
}
}
ここの、イベントソース ComponentChangedEventArgs のプロパティ Member が null でした。
えぇ・・。所詮はサンプルソースということなのですね。