Visual Studio 2015 に付随するMSBuildを使用して作成されたbamlをexe実行時に読み込んだ際どのように展開されいるのかを確認するためのコードは以下です。
コード:
using System;
using System.IO;
using System.Reflection;
using System.Windows;
namespace ConsoleApplication1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
var projectPath = $@"{Environment.ExpandEnvironmentVariables(@"%USERPROFILE%")}\Documents\visual studio 2015\Projects\C#\WpfApplication1";
var assembly = Assembly.LoadFile($@"{projectPath}\WpfApplication1\bin\Debug\WpfApplication1.exe");
using (var stream = new FileStream($@"{projectPath}\WpfApplication1\obj\Debug\MainWindow.baml", FileMode.Open))
using (var reader = new System.Windows.Baml2006.Baml2006Reader(stream, new System.Xaml.XamlReaderSettings { LocalAssembly = assembly }))
{
while (reader.Read())
{
Console.WriteLine("----------------------------------------");
Console.WriteLine($"NodeType: {reader.NodeType}");
Console.WriteLine($"Member: {reader.Member}");
Console.WriteLine($"Namespace: {reader.Namespace?.Namespace}");
Console.WriteLine($"SchemaContext: {reader.SchemaContext}");
//foreach (var name in reader.SchemaContext.GetAllXamlNamespaces())
// foreach (var type in reader.SchemaContext.GetAllXamlTypes(name))
// {
// if (type.ContentProperty == null) continue;
// Console.WriteLine(type.ContentProperty);
// break;
// }
Console.WriteLine($"Type: {reader.Type}");
Console.WriteLine($"Value: {reader.Value}");
}
}
Console.ReadKey();
}
}
}
コード:
<Window.Resources>
<local:ColorConverter x:Key="colorConverter"/>
</Window.Resources>
----------------------------------------
NodeType: StartMember
Member: System.Windows.FrameworkElement.Resources
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: GetObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.ResourceDictionary.DeferrableContent
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: Value
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value: System.IO.MemoryStream
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
コード:
<Window.Resources>
<ResourceDictionary>
<local:ColorConverter x:Key="colorConverter"/>
</ResourceDictionary>
</Window.Resources>
----------------------------------------
NodeType: StartMember
Member: System.Windows.FrameworkElement.Resources
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: System.Windows.ResourceDictionary
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.ResourceDictionary.DeferrableContent
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: Value
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value: System.IO.MemoryStream
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
コード:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:ColorConverter x:Key="colorConverter"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
----------------------------------------
NodeType: StartMember
Member: System.Windows.FrameworkElement.Resources
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: System.Windows.ResourceDictionary
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.ResourceDictionary.MergedDictionaries
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: GetObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartMember
Member: {http://schemas.microsoft.com/winfx/2006/xaml}_Items
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: System.Windows.ResourceDictionary
Value:
----------------------------------------
NodeType: StartMember
Member: {http://schemas.microsoft.com/winfx/2006/xaml}_Items
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: WpfApplication1.ColorConverter
Value:
----------------------------------------
NodeType: StartMember
Member: {http://schemas.microsoft.com/winfx/2006/xaml}Key
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: Value
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value: colorConverter
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
コード:
<Ellipse>
<Ellipse.Fill>
<Binding Path="Switching">
<Binding.Converter>
<local:ColorConverter/>
</Binding.Converter>
</Binding>
</Ellipse.Fill>
</Ellipse>
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: System.Windows.Shapes.Ellipse
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.Shapes.Shape.Fill
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: System.Windows.Data.Binding
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.Data.Binding.Path
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: Value
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value: System.Windows.Baml2006.TypeConverterMarkupExtension
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartMember
Member: System.Windows.Data.Binding.Converter
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: StartObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type: WpfApplication1.ColorConverter
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndMember
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
NodeType: EndObject
Member:
Namespace:
SchemaContext: System.Windows.Baml2006.Baml2006SchemaContext
Type:
Value:
----------------------------------------
System.Windows.Baml2006.Baml2006SchemaContext とは
----------------------------------------
http://schemas.microsoft.com/winfx/2006 ... esentation
http://schemas.microsoft.com/xps/2005/0 ... tstructure
http://schemas.microsoft.com/xps/2005/06
http://schemas.microsoft.com/winfx/2006/xaml
http://schemas.microsoft.com/netfx/2009 ... esentation
http://schemas.microsoft.com/winfx/2006 ... osite-font
http://schemas.microsoft.com/netfx/2007 ... esentation
上記のような各スキーマで定義されているXamlで使用される型やらContentPropertyやらの情報が大量に格納されている
----------------------------------------
System.Windows.ResourceDictionary.DeferrableContent とは
-----------------------------------------------
Reference Sourceで確認するとコメントで記載されていますが
This should only be called in the deferred BAML loading scenario.
We cache all the data that we need away and then get rid of the actual object.
No one needs to actually get this property so we're returning null.
This property has to be public since the XAML parser cannot set this internal property in this scenario.
これは遅延BAMLロードシナリオでのみ呼び出されるべきです。
必要なすべてのデータをキャッシュし、実際のオブジェクトを取り除きます。
誰も実際にこのプロパティを取得する必要はありませんので、nullを返します。
このシナリオでは、XAMLパーサーはこの内部プロパティを設定できないため、このプロパティはパブリックである必要があります。
-----------------------------------------------
System.Windows.Markup.XamlReader.Load を使用してbamlを読み込んだ際、DeferrableContentが使用されていることを確認するためのコードは以下です。
オフトピック
Embed Resource (WpfApplication1.g.resources) として MainWindow.baml をアセンブリに埋め込まれた状態で、System.Windows.Markup.XamlReader.Load(System.Windows.Baml2006.Baml2006Reader)で再度 MainWindow.baml を読み込んだ場合、以下のエラーが出ます。
コード:
using System;
using System.IO;
using System.Reflection;
using System.Windows;
namespace ConsoleApplication1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
var projectPath = $@"{Environment.ExpandEnvironmentVariables(@"%USERPROFILE%")}\Documents\visual studio 2015\Projects\C#\WpfApplication1";
var assembly = Assembly.LoadFile($@"{projectPath}\WpfApplication1\bin\Debug\WpfApplication1.exe");
using (var stream = new FileStream($@"{projectPath}\WpfApplication1\obj\Debug\MainWindow.baml", FileMode.Open))
using (var reader = new System.Windows.Baml2006.Baml2006Reader(stream, new System.Xaml.XamlReaderSettings { LocalAssembly = assembly }))
{
//エラーが発生する箇所
var window = System.Windows.Markup.XamlReader.Load(reader) as Window;
Console.WriteLine(window.Resources["colorConverter"].GetType());
new Application().Run(window);
}
}
}
}
コード:
System.Windows.Markup.XamlParseException が発生しました。
HResult=-2146233087
LineNumber=11
LinePosition=6
Message='プロパティ 'System.Windows.ResourceDictionary.DeferrableContent' の Set で例外がスローされました。' 行番号 '11'、行位置 '6'。
Source=PresentationFramework
StackTrace:
場所 System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
場所 System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, Boolean skipJournaledProperties, Uri baseUri)
場所 System.Windows.Markup.XamlReader.Load(XamlReader xamlReader, ParserContext parserContext)
場所 System.Windows.Markup.XamlReader.Load(XamlReader reader)
場所 ConsoleApplication1.Program.Main(String[] args) 場所 C:\Users\Griff\documents\visual studio 2015\Projects\C#\ConsoleApplication1\ConsoleApplication1\Program.cs:行 33
InnerException:
HResult=-2147024809
Message=項目は既に追加されています。辞書のキー: 'colorConverter' 追加されるキー:'colorConverter'
Source=mscorlib
StackTrace:
場所 System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
場所 System.Collections.Hashtable.Add(Object key, Object value)
場所 System.Windows.ResourceDictionary.SetKeys(IList`1 keyCollection, IServiceProvider serviceProvider)
場所 System.Windows.ResourceDictionary.SetDeferrableContent(DeferrableContent deferrableContent)
場所 System.Windows.Baml2006.WpfSharedBamlSchemaContext.<>c.<Create_BamlProperty_ResourceDictionary_DeferrableContent>b__297_0(Object target, Object value)
場所 System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value)
場所 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value)
場所 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
InnerException: