Control のベースクラスを作る。
コントロールを作成するとき UserControl を直接継承するのではなく、間に一枚噛ますことが多いと思います。以下のような感じです。
namespace MyApp { public class ControlBase : UserControl { } }
で、この ControlBase クラスを継承してコントロールを作ります。
namespace MyApp { public class MyControl : ControlBase { } }
XAML は純粋に考えると以下のような感じ。
<local:ControlBase x:Class="MyApp.MyControl" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyApp" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </local:ControlBase>
まぁ、先に「純粋に考えると・・・」なんて書き方してるのでお分かりだと思いますが、これ、動きません。
実行すると「AG_E_UNKNOWN_ERROR」って怒られてしまいます。そうですか、わかりませんせんか。僕もわかりません。
動くようにするためには以下のようにアセンブリに XmlnsDefinitionAttribute を設定します。
using System.Windows.Markup; [assembly: XmlnsDefinition("http://schemas.microsoft.com/client/2007","MyApp")]
で、 xaml の宣言の部分でネームスペースを外してあげます。
<ControlBase x:Class="MyApp.MyControl" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </ControlBase>
これで動きます。
XmlnsDefinitionAttribute ですが、ドキュメントを見てみると、どうやら指定された XML のネームスペースに、指定された .NET の namespace の探索を追加するらしいです。
まぁ、確かに。そういう動きですね。
でもね、最初のネームスペースを明示的に指定するのも間違ってないと思うのですよ。 XML 的には。 XAML 的に間違ってるのか??ちょっと調べてみなきゃです。
あと、先日書いた XamlReader でこの MyControl を読み込んだ時の挙動も若干気になります。
※Beta 2 で挙動が変わりました。詳しくはこちら:Beta 2 で挙動が変わったところ。その1