staticなコントロールとデザイナの不具合
About
WPFでは"InvalidOperationException: 指定された要素は、既に別の要素の論理子です。まず接続を切断してください。"というエラーを起こします。これは、既にあるコントロールAの子要素として配置されたコントロールを、異なるコントロールBの子要素として配置しようとした場合に発生します。
しかしながら特殊な条件下では、親子関係がない状態であっても、このようなエラーが通知されます。実行時には問題がないのに、VisualStudioのデザイナ上でエラーが発生し、そのエラーを追ってみると、先のエラーを引き起こしている、と通知される場合です。下の画像のような状況です。ここではこの問題について具体例を挙げて原因を解説します。残念なことに、正しい解決方法については分かっていません。
- WpfApplication_StaticControlTest.zip
- VisualStudio2012
- .Netframework4.5
staticなコントロールを子要素にするコントロールに注意する
先のようなエラーは、staticなコントロールを子要素とするコントロールを、子要素とするコントロールで発生します。文面では構造が分かりにくいのですが、およそ次のような構造です。
- Window
- コントロール
- staticなコントロール
- コントロール
- コントロール
- コントロール
- staticなコントロール
- コントロール
実際に"staticなコントロールを持つコントロール"を作ってみると、例えば次のようになります。ここではUserControlと(staticな)Ellipseですが、コントロールの組み合わせはこれの限りではありません。
public partial class ChildUserControl : UserControl { public static Ellipse TargetEllipse = new Ellipse() { Width = 20, Height = 20, Fill = Brushes.Blue }; public ChildUserControl() { InitializeComponent(); this.grid.Children.Add(TargetEllipse); } }
このコントロールをWindowコントロールに追加するか、2階層以上の親となるコントロールなどに追加すると、VisualStudioのデザイナ上で不具合が生じます。
この問題の解決方法は、残念ながら私にはわかりません。そもそもこのような設計に問題があるかどうかも検証する必要があります。staticなコントロールを排除するとき、この問題は発生しません。またデザイナ上でのみ不具合が発生している状態で、ビルドや実行に不具合を来しません。したがって放置することも考えられますが、エラーを残しておくことは気持ちの良いものではありませんので、何かしらの方法で解決する必要があります。
このページの内容で通知される可能性のあるエラー
- XamlParseException: '指定されたバインディング制約に一致する型 'XXX' のコンストラクターの呼び出しで例外がスローされました。
- TargetInvocationException: 呼び出しのターゲットが例外をスローしました。
- InvalidOperationException: 指定された要素は、既に別の要素の論理子です。まず接続を切断してください。