イメージ 1
図1 ビルドエラー

MC3093: 要素 'TestControl' で Name 属性値 'testcont102' を設定することはできません。'TestControl' は、要素 'ExtendedGrid' のスコープ内にあり、この要素には、別のスコープで定義されたときに既に名前が登録されています。

WPFのアプリケーションを開発してる時に謎のエラーに当たりましたので、発生状況、対処法、原因の考察についてご紹介いたします。

発生状況

このビルドエラーには次の状況で遭遇しました。

イメージ 2
図2 XAMLを利用して既存のPanel系コントロールを拡張

イメージ 3
図3 拡張したPanel系コントロールに別のコントロールを追加

  • 既存のPanel系コントロール (Gridなど) を継承して、拡張したコントロールを定義
  • 拡張の際、XAMLを利用 (図2)
  • 拡張したPanel系コントロールをウィンドウなどの別のコントロールのXAMLで利用
  • そのXAMLの中で拡張したPanel系コントロールに別のコントロールを追加
  • 追加したコントロールにx:Nameで名前を付与 (図3)

なかなか既存のPanel系コントロールを強引に拡張する機会がまず少ないですが、だからなのかこのエラーに関する情報も見つからなかったので、あえて書いておきます。。

対処法

すべてのビルドエラーMC3093が同じ原因により発生しているという保証ができないので、なんとも言えませんが、とりあえず上記状況で発生したものに関しては、次の方法で対処しました。
対処法は、2つあります。

x:Nameの付与をやめる

拡張したPanel系コントロールの利用側で、追加したコントロールへのx:Nameをしなければ、このビルドエラーは回避できます。
不要ならば削除してしまいましょう。

拡張時にXAMLを使用しない

この方法は、ざっくり言えばPanel系コントロールを拡張する際に図2のようなXAMLを使用しないことです。
私がこの例外に陥った時は、XAMLとコード混みでGridなどを継承して拡張をおこなっておりました。しかし、実際の拡張の実装はすべてコードでやっていたので本当はXAMLは不要だったんです。ということでとりあえずコードファイル (*.cs) ファイルだけ残して、XAMLファイル (*.xaml) を削除したら、問題は解決しました。

原因の考察

Panel系コントロールを拡張する際、XAMLソースも混みでやってしまうと、その拡張したコントロールに添付されているXAMLファイル側でコントロールの追加が可能になります。エラーメッセージの言う「別のスコープ」とは恐らく、この拡張時に作ってしまったXAMLファイルのことを指しているのかと。
よくわかりませんんが、拡張側のXAMLスコープと利用側のXAMLスコープの両方でx:Nameが付与されることを警戒しているのがこのビルドエラーなのかなと。
はっきり言って原因はよくわからないのが現状です…。

その他

Panel系コントロールを継承して拡張するのはあまり正攻法とされていないようですので、もっと別の手段で拡張したほうが良さそうですね。