Browse Source

Merge pull request #1079 from AvaloniaUI/portablexaml

Portablexaml
pull/1084/head
Nikita Tsukanov 9 years ago
committed by GitHub
parent
commit
8ef565d9b1
  1. 9
      .gitmodules
  2. 3
      build.cake
  3. 4
      build/Markup.props
  4. 12
      build/XUnit.props
  5. 68
      packages.cake
  6. 2
      samples/BindingTest/BindingTest.csproj
  7. 2
      samples/BindingTest/MainWindow.xaml
  8. 4
      samples/BindingTest/ViewModels/MainWindowViewModel.cs
  9. 2
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  10. 2
      samples/ControlCatalog/ControlCatalog.csproj
  11. 2
      samples/RenderTest/RenderTest.csproj
  12. 2
      samples/VirtualizationTest/VirtualizationTest.csproj
  13. 2
      samples/interop/GtkInteropDemo/GtkInteropDemo.csproj
  14. 2
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  15. 2
      src/Avalonia.Animation/Avalonia.Animation.csproj
  16. 2
      src/Avalonia.Base/Avalonia.Base.csproj
  17. 15
      src/Avalonia.Base/Metadata/AmbientAttribute.cs
  18. 15
      src/Avalonia.Base/Metadata/TemplateContent.cs
  19. 2
      src/Avalonia.Controls/Avalonia.Controls.csproj
  20. 45
      src/Avalonia.Controls/Control.cs
  21. 9
      src/Avalonia.Controls/Panel.cs
  22. 2
      src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj
  23. 2
      src/Avalonia.DesignerSupport/DesignerAssist.cs
  24. 2
      src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj
  25. 2
      src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
  26. 2
      src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj
  27. 2
      src/Avalonia.Input/Avalonia.Input.csproj
  28. 2
      src/Avalonia.Interactivity/Avalonia.Interactivity.csproj
  29. 2
      src/Avalonia.Layout/Avalonia.Layout.csproj
  30. 2
      src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj
  31. 2
      src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
  32. 2
      src/Avalonia.Styling/Avalonia.Styling.csproj
  33. 21
      src/Avalonia.Styling/Styling/Style.cs
  34. 90
      src/Avalonia.Styling/Styling/StyleResources.cs
  35. 2
      src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj
  36. 2
      src/Avalonia.Visuals/Avalonia.Visuals.csproj
  37. 2
      src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj
  38. 2
      src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
  39. 2
      src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
  40. 326
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  41. 228
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
  42. 215
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs
  43. 33
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaAttachableXamlMember.cs
  44. 58
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaContentPropertyProvider.cs
  45. 31
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaLifeCycleListener.cs
  46. 25
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaMemberValuePlugin.cs
  47. 181
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs
  48. 79
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaObjectAssembler.cs
  49. 41
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaParserFactory.cs
  50. 91
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaRuntimeTypeSource.cs
  51. 180
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs
  52. 28
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeRepository.cs
  53. 126
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaWiringContext.cs
  54. 31
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaXamlMember.cs
  55. 61
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaXamlType.cs
  56. 30
      src/Markup/Avalonia.Markup.Xaml/Context/NameScopeWrapper.cs
  57. 174
      src/Markup/Avalonia.Markup.Xaml/Context/PropertyAccessor.cs
  58. 21
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaListTypeConverter.cs
  59. 44
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
  60. 31
      src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs
  61. 21
      src/Markup/Avalonia.Markup.Xaml/Converters/BrushTypeConverter.cs
  62. 20
      src/Markup/Avalonia.Markup.Xaml/Converters/ClassesTypeConverter.cs
  63. 21
      src/Markup/Avalonia.Markup.Xaml/Converters/ColorTypeConverter.cs
  64. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs
  65. 23
      src/Markup/Avalonia.Markup.Xaml/Converters/CursorTypeConverter.cs
  66. 58
      src/Markup/Avalonia.Markup.Xaml/Converters/DateTimeTypeConverter.cs
  67. 39
      src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs
  68. 28
      src/Markup/Avalonia.Markup.Xaml/Converters/GeometryTypeConverter.cs
  69. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/GridLengthTypeConverter.cs
  70. 51
      src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs
  71. 22
      src/Markup/Avalonia.Markup.Xaml/Converters/KeyGestureConverter.cs
  72. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/MemberSelectorTypeConverter.cs
  73. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/PointTypeConverter.cs
  74. 20
      src/Markup/Avalonia.Markup.Xaml/Converters/PointsListTypeConverter.cs
  75. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/RelativePointTypeConverter.cs
  76. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/RelativeRectTypeConverter.cs
  77. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs
  78. 21
      src/Markup/Avalonia.Markup.Xaml/Converters/SelectorTypeConverter.cs
  79. 49
      src/Markup/Avalonia.Markup.Xaml/Converters/SetterValueTypeConverter.cs
  80. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/SizeTypeConverter.cs
  81. 19
      src/Markup/Avalonia.Markup.Xaml/Converters/ThicknessTypeConverter.cs
  82. 24
      src/Markup/Avalonia.Markup.Xaml/Converters/TimeSpanTypeConverter.cs
  83. 32
      src/Markup/Avalonia.Markup.Xaml/Converters/UriTypeConverter.cs
  84. 27
      src/Markup/Avalonia.Markup.Xaml/Data/SourceBindingEndpoint.cs
  85. 4
      src/Markup/Avalonia.Markup.Xaml/Data/StyleResourceBinding.cs
  86. 18
      src/Markup/Avalonia.Markup.Xaml/Data/TargetBindingEndpoint.cs
  87. 23
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
  88. 7
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs
  89. 86
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/Standard/StaticExtension.cs
  90. 49
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/Standard/TypeExtension.cs
  91. 73
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticExtension.cs
  92. 30
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
  93. 18
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs
  94. 13
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TemplateBindingExtension.cs
  95. 34
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TypeExtension.cs
  96. 1
      src/Markup/Avalonia.Markup.Xaml/OmniXAML
  97. 39
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AttributeExtensions.cs
  98. 86
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs
  99. 71
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaMemberAttributeProvider.cs
  100. 56
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaNameScope.cs

9
.gitmodules

@ -5,9 +5,6 @@
path = src/Avalonia.HtmlRenderer/external
url = https://github.com/AvaloniaUI/HTML-Renderer.git
branch = perspex-pcl
[submodule "src/Markup/Avalonia.Markup.Xaml/OmniXAML"]
path = src/Markup/Avalonia.Markup.Xaml/OmniXAML
url = https://github.com/AvaloniaUI/OmniXAML.git
[submodule "src/Markup/Avalonia.Markup.Xaml/glass"]
path = src/Markup/Avalonia.Markup.Xaml/glass
url = https://github.com/SuperJMN/glass
[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"]
path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github
url = https://github.com/cwensley/Portable.Xaml.git

3
build.cake

@ -403,7 +403,8 @@ Task("Inspect")
{
var badIssues = new []{"PossibleNullReferenceException"};
var whitelist = new []{"tests", "src\\android", "src\\ios",
"src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external"};
"src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external",
"src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"};
Information("Running code inspections");

4
build/Markup.props

@ -5,5 +5,9 @@
<PackageReference Include="System.Linq" Version="4.3.0" />
<PackageReference Include="System.Runtime" Version="4.3.0" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
<PackageReference Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
<PackageReference Include="System.ComponentModel.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
</ItemGroup>
</Project>

12
build/XUnit.props

@ -12,4 +12,16 @@
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.1'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
</ItemGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<Target Name="ForceGenerationOfBindingRedirects"
AfterTargets="ResolveAssemblyReferences"
BeforeTargets="GenerateBindingRedirects"
Condition="'$(AutoGenerateBindingRedirects)' == 'true'">
<PropertyGroup>
<!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets -->
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
</Target>
</Project>

68
packages.cake

@ -8,6 +8,42 @@ public class Packages
public string NugetPackagesDir {get; private set;}
public string SkiaSharpVersion {get; private set; }
public string SkiaSharpLinuxVersion {get; private set; }
public Dictionary<string, IList<Tuple<string,string>>> PackageVersions{get; private set;}
class DependencyBuilder : List<NuSpecDependency>
{
Packages _parent;
public DependencyBuilder(Packages parent)
{
_parent = parent;
}
string GetVersion(string name)
{
return _parent.PackageVersions[name].First().Item1;
}
public DependencyBuilder Dep(string name, params string[] fws)
{
if(fws.Length == 0)
Add(new NuSpecDependency() { Id = name, Version = GetVersion(name) });
foreach(var fw in fws)
Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) });
return this;
}
public DependencyBuilder Deps(string[] fws, params string[] deps)
{
foreach(var fw in fws)
foreach(var name in deps)
Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) });
return this;
}
}
//new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
public Packages(ICakeContext context, Parameters parameters)
{
// NUGET NUSPECS
@ -26,7 +62,7 @@ public class Packages
// Key: Package Id
// Value is Tuple where Item1: Package Version, Item2: The *.csproj/*.props file path.
var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
PackageVersions = packageVersions;
System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./build")).FullPath,
"*.props", SearchOption.AllDirectories).ToList().ForEach(fileName =>
{
@ -150,12 +186,12 @@ public class Packages
};
var coreLibrariesFiles = coreLibraries.Select((lib) => {
return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.1/" + lib[1] + lib[2]);
return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.3/" + lib[1] + lib[2]);
}).ToList();
var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
return new NuSpecContent {
Source = file.FullPath, Target = "lib/netstandard1.1"
Source = file.FullPath, Target = "lib/netstandard1.3"
};
});
@ -195,13 +231,12 @@ public class Packages
new NuGetPackSettings()
{
Id = "Avalonia",
Dependencies = new []
Dependencies = new DependencyBuilder(this)
{
new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion },
new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
new NuSpecDependency() { Id = "System.ValueTuple", Version = SystemValueTupleVersion },
//.NET Core
new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
new NuSpecDependency() { Id = "Microsoft.Extensions.DependencyModel", TargetFramework = "netcoreapp1.0", Version = "1.1.0" },
@ -210,8 +245,11 @@ public class Packages
new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = SerilogVersion },
new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp1.0", Version = SpracheVersion },
new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp1.0", Version = SystemReactiveVersion },
new NuSpecDependency() { Id = "System.ValueTuple", TargetFramework = "netcoreapp1.0", Version = SystemValueTupleVersion }
},
}
.Deps(new string[]{null, "netcoreapp1.0"},
"System.ValueTuple", "System.ComponentModel.TypeConverter", "System.ComponentModel.Primitives",
"System.Runtime.Serialization.Primitives", "System.Xml.XmlDocument")
.ToArray(),
Files = coreLibrariesNuSpecContent
.Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform)
.Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform)
@ -231,9 +269,9 @@ public class Packages
},
Files = new []
{
new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.1" }
new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.3" }
},
BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.1"),
BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.3"),
OutputDirectory = parameters.NugetRoot
}
};
@ -347,7 +385,7 @@ public class Packages
Files = new []
{
new NuSpecContent { Source = "Avalonia.Win32/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/net45" },
new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.1/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.3/Avalonia.Win32.dll", Target = "lib/netstandard1.3" }
},
BasePath = context.Directory("./src/Windows"),
OutputDirectory = parameters.NugetRoot
@ -402,9 +440,9 @@ public class Packages
},
Files = new []
{
new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" }
new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.3" }
},
BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.1"),
BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.3"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
@ -460,9 +498,9 @@ public class Packages
new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="net45", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="net45", Version = parameters.Version },
//.NET Core
new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp1.1", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="netcoreapp1.1", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp1.1", Version = parameters.Version }
new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp1.0", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="netcoreapp1.0", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp1.0", Version = parameters.Version }
},
Files = new NuSpecContent[]
{

2
samples/BindingTest/BindingTest.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BindingTest</RootNamespace>
<AssemblyName>BindingTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />

2
samples/BindingTest/MainWindow.xaml

@ -44,6 +44,8 @@
<StackPanel Margin="18" Gap="4" Width="200" HorizontalAlignment="Left">
<TextBlock FontSize="16" Text="Scheduler"/>
<TextBox Watermark="Background Thread" Text="{Binding CurrentTime, Mode=OneWay}"/>
<TextBlock FontSize="16" Text="Stream Operator"/>
<TextBox Watermark="StreamOperator" Text="{Binding CurrentTimeObservable^, Mode=OneWay}"/>
</StackPanel>
</StackPanel>
</StackPanel>

4
samples/BindingTest/ViewModels/MainWindowViewModel.cs

@ -49,6 +49,9 @@ namespace BindingTest.ViewModels
Thread.Sleep(1000);
}
});
CurrentTimeObservable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
.Select(x => DateTimeOffset.Now.ToString());
}
public ObservableCollection<TestItem> Items { get; }
@ -85,6 +88,7 @@ namespace BindingTest.ViewModels
private set { this.RaiseAndSetIfChanged(ref _currentTime, value); }
}
public IObservable<string> CurrentTimeObservable { get; }
public ReactiveCommand<object> StringValueCommand { get; }
public DataAnnotationsErrorViewModel DataAnnotationsValidation { get; } = new DataAnnotationsErrorViewModel();

2
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ControlCatalog.Desktop</RootNamespace>
<AssemblyName>ControlCatalog.Desktop</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />

2
samples/ControlCatalog/ControlCatalog.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

2
samples/RenderTest/RenderTest.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RenderTest</RootNamespace>
<AssemblyName>RenderTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />

2
samples/VirtualizationTest/VirtualizationTest.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VirtualizationTest</RootNamespace>
<AssemblyName>VirtualizationTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />

2
samples/interop/GtkInteropDemo/GtkInteropDemo.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GtkInteropDemo</RootNamespace>
<AssemblyName>GtkInteropDemo</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>

2
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WindowsInteropTest</RootNamespace>
<AssemblyName>WindowsInteropTest</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>

2
src/Avalonia.Animation/Avalonia.Animation.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.Base/Avalonia.Base.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

15
src/Avalonia.Base/Metadata/AmbientAttribute.cs

@ -0,0 +1,15 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.Metadata
{
/// <summary>
/// Defines the ambient class/property
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true)]
public class AmbientAttribute : Attribute
{
}
}

15
src/Avalonia.Base/Metadata/TemplateContent.cs

@ -0,0 +1,15 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.Metadata
{
/// <summary>
/// Defines the property that contains the object's content in markup.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class TemplateContentAttribute : Attribute
{
}
}

2
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

45
src/Avalonia.Controls/Control.cs

@ -355,18 +355,28 @@ namespace Avalonia.Controls
if (--_initCount == 0 && _isAttachedToLogicalTree)
{
if (!_styled)
{
RegisterWithNameScope();
ApplyStyling();
_styled = true;
}
InitializeStylesIfNeeded();
if (!IsInitialized)
{
IsInitialized = true;
Initialized?.Invoke(this, EventArgs.Empty);
}
InitializeIfNeeded();
}
}
private void InitializeStylesIfNeeded(bool force = false)
{
if (_initCount == 0 && (!_styled || force))
{
RegisterWithNameScope();
ApplyStyling();
_styled = true;
}
}
private void InitializeIfNeeded()
{
if (_initCount == 0 && !IsInitialized)
{
IsInitialized = true;
Initialized?.Invoke(this, EventArgs.Empty);
}
}
@ -580,11 +590,7 @@ namespace Avalonia.Controls
{
base.OnAttachedToVisualTreeCore(e);
if (!IsInitialized)
{
IsInitialized = true;
Initialized?.Invoke(this, EventArgs.Empty);
}
InitializeIfNeeded();
}
/// <inheritdoc/>
@ -752,12 +758,7 @@ namespace Avalonia.Controls
{
_isAttachedToLogicalTree = true;
if (_initCount == 0)
{
RegisterWithNameScope();
ApplyStyling();
_styled = true;
}
InitializeStylesIfNeeded(true);
OnAttachedToLogicalTree(e);
}

9
src/Avalonia.Controls/Panel.cs

@ -64,9 +64,12 @@ namespace Avalonia.Controls
{
Contract.Requires<ArgumentNullException>(value != null);
VisualChildren.Clear();
_children.Clear();
_children.AddRange(value);
if (_children != value)
{
VisualChildren.Clear();
_children.Clear();
_children.AddRange(value);
}
}
}

2
src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.DesignerSupport/DesignerAssist.cs

@ -5,8 +5,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using OmniXaml;
using OmniXaml.ObjectAssembler;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Markup.Xaml;

2
src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Avalonia.DotNetFrameworkRuntime</RootNamespace>
<AssemblyName>Avalonia.DotNetFrameworkRuntime</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

2
src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<EnableDefaultItems>False</EnableDefaultItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

2
src/Avalonia.Input/Avalonia.Input.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.Interactivity/Avalonia.Interactivity.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.Layout/Avalonia.Layout.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

2
src/Avalonia.Styling/Avalonia.Styling.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

21
src/Avalonia.Styling/Styling/Style.cs

@ -13,10 +13,10 @@ namespace Avalonia.Styling
/// </summary>
public class Style : IStyle
{
private static Dictionary<IStyleable, List<IDisposable>> _applied =
private static Dictionary<IStyleable, List<IDisposable>> _applied =
new Dictionary<IStyleable, List<IDisposable>>();
private Dictionary<string, object> _resources;
private StyleResources _resources;
/// <summary>
/// Initializes a new instance of the <see cref="Style"/> class.
@ -37,13 +37,13 @@ namespace Avalonia.Styling
/// <summary>
/// Gets or sets a dictionary of style resources.
/// </summary>
public IDictionary<string, object> Resources
public StyleResources Resources
{
get
{
if (_resources == null)
{
_resources = new Dictionary<string, object>();
_resources = new StyleResources();
}
return _resources;
@ -51,11 +51,16 @@ namespace Avalonia.Styling
set
{
var resources = Resources;
foreach (var i in value)
if (!Equals(resources, value))
{
resources.Add(i);
foreach (var i in value)
{
resources[i.Key] = i.Value;
//resources.Add(i.Key, i.Value);
//(resources as IDictionary<string,object>).Add(i);
}
}
}
}
@ -69,7 +74,7 @@ namespace Avalonia.Styling
/// Gets or sets the style's setters.
/// </summary>
[Content]
public IEnumerable<ISetter> Setters { get; set; } = new List<ISetter>();
public IList<ISetter> Setters { get; set; } = new List<ISetter>();
/// <summary>
/// Attaches the style to a control if the style's selector matches.

90
src/Avalonia.Styling/Styling/StyleResources.cs

@ -0,0 +1,90 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Avalonia.Styling
{
/// <summary>
/// Holds resources for a <see cref="Style"/>.
/// </summary>
public class StyleResources : IDictionary<string, object>, IDictionary
{
private Dictionary<string, object> _inner = new Dictionary<string, object>();
public object this[string key]
{
get { return _inner[key]; }
set { _inner[key] = value; }
}
public int Count => _inner.Count;
ICollection<string> IDictionary<string, object>.Keys => _inner.Keys;
ICollection<object> IDictionary<string, object>.Values => _inner.Values;
bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false;
object IDictionary.this[object key]
{
get { return ((IDictionary)_inner)[key]; }
set { ((IDictionary)_inner)[key] = value; }
}
ICollection IDictionary.Keys => _inner.Keys;
ICollection IDictionary.Values => _inner.Values;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => ((IDictionary)_inner).SyncRoot;
bool IDictionary.IsFixedSize => false;
bool IDictionary.IsReadOnly => false;
public void Add(string key, object value) => _inner.Add(key, value);
public void Clear() => _inner.Clear();
public bool ContainsKey(string key) => _inner.ContainsKey(key);
public bool Remove(string key) => _inner.Remove(key);
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => _inner.GetEnumerator();
public bool TryGetValue(string key, out object value) => _inner.TryGetValue(key, out value);
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
{
return ((IDictionary<string, object>)_inner).Contains(item);
}
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
{
((IDictionary<string, object>)_inner).Add(item);
}
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
((IDictionary<string, object>)_inner).CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
{
return ((IDictionary<string, object>)_inner).Remove(item);
}
void ICollection.CopyTo(Array array, int index) => ((IDictionary)_inner).CopyTo(array, index);
IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator();
IDictionaryEnumerator IDictionary.GetEnumerator() => ((IDictionary)_inner).GetEnumerator();
void IDictionary.Add(object key, object value) => ((IDictionary)_inner).Add(key, value);
bool IDictionary.Contains(object key) => ((IDictionary)_inner).Contains(key);
void IDictionary.Remove(object key) => ((IDictionary)_inner).Remove(key);
}
}

2
src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

2
src/Avalonia.Visuals/Avalonia.Visuals.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Avalonia</RootNamespace>
</PropertyGroup>

2
src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Avalonia.Cairo</RootNamespace>
<AssemblyName>Avalonia.Cairo</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>

2
src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj

@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>Avalonia.Gtk</RootNamespace>
<AssemblyName>Avalonia.Gtk</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>

2
src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

326
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -1,273 +1,98 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<TargetFramework>netstandard1.3</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<EnableDefaultItems>false</EnableDefaultItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG;NETSTANDARD1_3;PCL;NETSTANDARD</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>NETSTANDARD1_3;PCL;NETSTANDARD</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Avalonia.Markup.Xaml.XML</DocumentationFile>
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\Shared\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Context\NameScopeWrapper.cs" />
<Compile Include="Context\AvaloniaAttachableXamlMember.cs" />
<Compile Include="Context\AvaloniaLifeCycleListener.cs" />
<Compile Include="Context\AvaloniaMemberValuePlugin.cs" />
<Compile Include="Context\AvaloniaNamespaceRegistry.cs" />
<Compile Include="Context\AvaloniaObjectAssembler.cs" />
<Compile Include="Context\AvaloniaTypeFeatureProvider.cs" />
<Compile Include="Context\AvaloniaParserFactory.cs" />
<Compile Include="Context\AvaloniaRuntimeTypeSource.cs" />
<Compile Include="Context\AvaloniaTypeRepository.cs" />
<Compile Include="Context\AvaloniaXamlMember.cs" />
<Compile Include="Context\AvaloniaXamlType.cs" />
<Compile Include="Context\PropertyAccessor.cs" />
<Compile Include="Converters\BitmapTypeConverter.cs" />
<Compile Include="Converters\BrushTypeConverter.cs" />
<Compile Include="Converters\ClassesTypeConverter.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
<Compile Include="Converters\CursorTypeConverter.cs" />
<Compile Include="Converters\DateTimeTypeConverter.cs" />
<Compile Include="Converters\FontWeightConverter.cs" />
<Compile Include="Converters\GeometryTypeConverter.cs" />
<Compile Include="Converters\GridLengthTypeConverter.cs" />
<Compile Include="Converters\IconTypeConverter.cs" />
<Compile Include="Converters\KeyGestureConverter.cs" />
<Compile Include="Converters\MemberSelectorTypeConverter.cs" />
<Compile Include="Converters\AvaloniaListTypeConverter.cs" />
<Compile Include="Converters\AvaloniaPropertyTypeConverter.cs" />
<Compile Include="Converters\PointsListTypeConverter.cs" />
<Compile Include="Converters\SizeTypeConverter.cs" />
<Compile Include="Converters\PointTypeConverter.cs" />
<Compile Include="Converters\RelativePointTypeConverter.cs" />
<Compile Include="Converters\RelativeRectTypeConverter.cs" />
<Compile Include="Converters\RowDefinitionsTypeConverter.cs" />
<Compile Include="Converters\SelectorTypeConverter.cs" />
<Compile Include="Converters\ThicknessTypeConverter.cs" />
<Compile Include="Converters\TimeSpanTypeConverter.cs" />
<Compile Include="Converters\UriTypeConverter.cs" />
<Compile Include="Data\Binding.cs" />
<Compile Include="Data\DelayedBinding.cs" />
<Compile Include="Data\MultiBinding.cs" />
<Compile Include="Data\RelativeSource.cs" />
<Compile Include="Data\SourceBindingEndpoint.cs" />
<Compile Include="Data\StyleResourceBinding.cs" />
<Compile Include="Data\TargetBindingEndpoint.cs" />
<Compile Include="glass\Glass.Core\AutoKeyDictionary.cs" />
<Compile Include="glass\Glass.Core\DependencySorter.cs" />
<Compile Include="glass\Glass.Core\EnumExtensions.cs" />
<Compile Include="glass\Glass.Core\Extensions.cs" />
<Compile Include="glass\Glass.Core\Guard.cs" />
<Compile Include="glass\Glass.Core\IAdd.cs" />
<Compile Include="glass\Glass.Core\IDependency.cs" />
<Compile Include="glass\Glass.Core\ReflectionExtensions.cs" />
<Compile Include="glass\Glass.Core\StackingLinkedList.cs" />
<Compile Include="glass\Glass.Core\StackingLinkedListMixin.cs" />
<Compile Include="MarkupExtensions\Standard\StaticExtension.cs" />
<Compile Include="MarkupExtensions\Standard\TypeExtension.cs" />
<Compile Include="MarkupExtensions\StyleResourceExtension.cs" />
<Compile Include="MarkupExtensions\BindingExtension.cs" />
<Compile Include="MarkupExtensions\RelativeSourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticExtension.cs" />
<Compile Include="MarkupExtensions\TemplateBindingExtension.cs" />
<Compile Include="MarkupExtensions\TypeExtension.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Attributes\ContentPropertyAttribute.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Attributes\DependsOnAttribute.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Attributes\XmlnsDefinitionAttribute.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\AddressPack.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\AssemblyNameConfig.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\ConfiguredAssembly.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\ConfiguredAssemblyWithNamespaces.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\ContentProperties.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\ContentPropertyDefinition.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\Converters.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\Route.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\TypeConverterRegistration.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\XamlInstructionBuilder.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Builder\XamlNamespace.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\DefaultLoader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\DefaultObjectAssemblerFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\DefaultParserFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\DeferredLoaderMapping.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\DependencySortingVisitor.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IContentPropertyProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IDeferredLoader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IInstanceLifeCycleListener.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ILoader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IMarkupExtension.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\INameScope.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\InstanceLifeCycleHandler.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Instruction.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\InstructionNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\InstructionTreeBuilder.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\InstructionType.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IObjectAssembler.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IObjectAssemblerFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IParserFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IRuntimeTypeSource.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ITypeFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ITypeFeatureProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ITypeProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\IValueConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\LoadException.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\LoadMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\LookaheadBuffer.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\MarkupExtension.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\MarkupExtensionContext.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\MemberDependencyNodeSorter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\MemberReverserVisitor.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\NamespaceDeclaration.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\NamespacePrefix.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssemblerMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Command.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\EndMemberCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\EndObjectCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\GetObjectCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\ITopDownValueContext.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\NamespaceDeclarationCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\StartMemberCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\StartObjectCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Commands\ValueCommand.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\ConstructionArgument.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\CurrentLevelWrapper.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\InstanceProperties.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Level.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\NullLevel.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\NullLifecycleListener.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\ObjectAssembler.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\PreviousLevelWrapper.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\Settings.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\StateCommuter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\StoredInstance.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\TopDownValueContext.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\TypeOperations.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\ValueProcessingMode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ObjectAssembler\XamlSetValueEventArgs.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ParseException.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\Inject.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\IParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\AssignmentNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\IdentifierNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\MarkupExtensionNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\MarkupExtensionNodeToXamlNodesConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\MarkupExtensionParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\Option.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\OptionsCollection.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\PositionalOption.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\PropertyOption.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\StringNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\MarkupExtensions\TreeNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\Parser\IInstructionParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\Parser\InstructionParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\Parser\OrderAwareInstructionParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\AttributeAssignment.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\AttributeFeed.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\AttributeParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\DirectiveAssignment.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\IProtoParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\IXmlReader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\NodeType.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\NsPrefix.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\ProtoInstructionParser.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\UnprocessedAttributeBase.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Parsers\ProtoParser\XmlCompatibilityReader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\PhaseParserKit.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\PrefixRegistrationMode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ProtoInstruction.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ProtoInstructionBuilder.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\RuntimeTypeSource.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Sequence.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TemplateHostingObjectAssembler.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\BuiltInConverters\BooleanConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\BuiltInConverters\DoubleTypeConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\BuiltInConverters\IntTypeConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\BuiltInConverters\StringTypeConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\BuiltInConverters\TypeTypeConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\ITypeConverter.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\ITypeConverterProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\IValueContext.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\TypeConverterAttribute.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\TypeConverterProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeConversion\ValueContext.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeFactory.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeFactoryMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeFeatureProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\TypeNotFoundException.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\AttachableMember.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\ClrNamespace.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\CommonValueConversion.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\CoreTypes.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\DependencyRegistration.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\DependencyRegistrations.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Directive.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\GenericMetadata.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\IMemberValuePlugin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\INamespaceRegistry.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\ITypeRepository.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Member.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MemberBase.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MemberValuePlugin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Metadata.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MetadataProvider.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MutableMember.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\NameAttribute.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Namespace.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\NamespaceRegistry.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\NamespaceRegistryMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\PrefixRegistration.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\PropertyLocator.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\TypeConverterProviderMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\TypeRepository.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\TypeRepositoryMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlName.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlQualifiedName.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlType.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlTypeName.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ValueConversionException.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\IVisitor.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\NodeType.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\NodeVisualizer.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\VisualizationNode.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\VisualizationTag.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\XmlLoader.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\XmlParser.cs" />
<Compile Include="Parsers\SelectorGrammar.cs" />
<Compile Include="Parsers\SelectorParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AvaloniaXamlLoader.cs" />
<Compile Include="Styling\StyleInclude.cs" />
<Compile Include="Templates\ControlTemplate.cs" />
<Compile Include="Templates\DataTemplate.cs" />
<Compile Include="Templates\FocusAdornerTemplate.cs" />
<Compile Include="Templates\ItemsPanelTemplate.cs" />
<Compile Include="Templates\MemberSelector.cs" />
<Compile Include="Templates\Template.cs" />
<Compile Include="Templates\TemplateContent.cs" />
<Compile Include="Templates\TemplateLoader.cs" />
<Compile Include="Templates\TreeDataTemplate.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AvaloniaXamlLoaderPortableXaml.cs" />
<Compile Include="AvaloniaXamlLoader.cs" />
<Compile Include="Converters\SetterValueTypeConverter.cs" />
<Compile Include="MarkupExtensions\StyleIncludeExtension.cs" />
<Compile Include="PortableXaml\AvaloniaXamlContext.cs" />
<Compile Include="PortableXaml\XamlBinding.cs" />
<Compile Include="PortableXaml\AttributeExtensions.cs" />
<Compile Include="PortableXaml\AvaloniaMemberAttributeProvider.cs" />
<Compile Include="PortableXaml\AvaloniaNameScope.cs" />
<Compile Include="PortableXaml\AvaloniaDefaultTypeConverters.cs" />
<Compile Include="PortableXaml\AvaloniaXamlObjectWriter.cs" />
<Compile Include="PortableXaml\AvaloniaRuntimeTypeProvider.cs" />
<Compile Include="PortableXaml\AvaloniaXamlSchemaContext.cs" />
<Compile Include="Converters\BitmapTypeConverter.cs" />
<Compile Include="Converters\BrushTypeConverter.cs" />
<Compile Include="Converters\ClassesTypeConverter.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
<Compile Include="Converters\CursorTypeConverter.cs" />
<Compile Include="Converters\GeometryTypeConverter.cs" />
<Compile Include="Converters\GridLengthTypeConverter.cs" />
<Compile Include="Converters\IconTypeConverter.cs" />
<Compile Include="Converters\KeyGestureConverter.cs" />
<Compile Include="Converters\MemberSelectorTypeConverter.cs" />
<Compile Include="Converters\AvaloniaListTypeConverter.cs" />
<Compile Include="Converters\AvaloniaPropertyTypeConverter.cs" />
<Compile Include="Converters\PointsListTypeConverter.cs" />
<Compile Include="Converters\SizeTypeConverter.cs" />
<Compile Include="Converters\PointTypeConverter.cs" />
<Compile Include="Converters\RelativePointTypeConverter.cs" />
<Compile Include="Converters\RelativeRectTypeConverter.cs" />
<Compile Include="Converters\RowDefinitionsTypeConverter.cs" />
<Compile Include="Converters\SelectorTypeConverter.cs" />
<Compile Include="Converters\ThicknessTypeConverter.cs" />
<Compile Include="Converters\TimeSpanTypeConverter.cs" />
<Compile Include="Data\Binding.cs" />
<Compile Include="Data\DelayedBinding.cs" />
<Compile Include="Data\MultiBinding.cs" />
<Compile Include="Data\RelativeSource.cs" />
<Compile Include="Data\StyleResourceBinding.cs" />
<Compile Include="MarkupExtensions\StyleResourceExtension.cs" />
<Compile Include="MarkupExtensions\BindingExtension.cs" />
<Compile Include="MarkupExtensions\RelativeSourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticExtension.cs" />
<Compile Include="MarkupExtensions\TemplateBindingExtension.cs" />
<Compile Include="MarkupExtensions\TypeExtension.cs" />
<Compile Include="Parsers\SelectorGrammar.cs" />
<Compile Include="Parsers\SelectorParser.cs" />
<Compile Include="PortableXaml\AvaloniaTypeAttributeProvider.cs" />
<Compile Include="PortableXaml\AvaloniaXamlType.cs" />
<Compile Include="PortableXaml\TypeDescriptorExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Styling\StyleInclude.cs" />
<Compile Include="Templates\ControlTemplate.cs" />
<Compile Include="Templates\DataTemplate.cs" />
<Compile Include="Templates\FocusAdornerTemplate.cs" />
<Compile Include="Templates\ItemsPanelTemplate.cs" />
<Compile Include="Templates\MemberSelector.cs" />
<Compile Include="Templates\Template.cs" />
<Compile Include="Templates\TemplateContent.cs" />
<Compile Include="Templates\TemplateLoader.cs" />
<Compile Include="Templates\TreeDataTemplate.cs" />
<Compile Include="PortableXaml\portable.xaml.github\src\Portable.Xaml\**\*.cs" Exclude="PortableXaml\portable.xaml.github\src\Portable.Xaml\Assembly\**\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Avalonia.Animation\Avalonia.Animation.csproj" />
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />
@ -279,11 +104,6 @@
<ProjectReference Include="..\..\Avalonia.Styling\Avalonia.Styling.csproj" />
<ProjectReference Include="..\Avalonia.Markup\Avalonia.Markup.csproj" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<Content Include="glass\Glass.Core\Glass.Core.csproj" />
</ItemGroup>
<Import Project="..\..\..\build\Markup.props" />
<Import Project="..\..\..\build\Sprache.props" />
<Import Project="..\..\..\build\Rx.props" />

228
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@ -1,225 +1,11 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using OmniXaml;
using Avalonia.Platform;
using Avalonia.Markup.Xaml.Context;
using Avalonia.Markup.Xaml.Styling;
using OmniXaml.ObjectAssembler;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.Data;
namespace Avalonia.Markup.Xaml
namespace Avalonia.Markup.Xaml
{
/// <summary>
/// Loads XAML for a avalonia application.
/// </summary>
public class AvaloniaXamlLoader : XmlLoader
public class AvaloniaXamlLoader : AvaloniaXamlLoaderPortableXaml
{
private static AvaloniaParserFactory s_parserFactory;
private static IInstanceLifeCycleListener s_lifeCycleListener = new AvaloniaLifeCycleListener();
private static Stack<Uri> s_uriStack = new Stack<Uri>();
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
/// </summary>
public AvaloniaXamlLoader()
: this(GetParserFactory())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
/// </summary>
/// <param name="xamlParserFactory">The parser factory to use.</param>
public AvaloniaXamlLoader(IParserFactory xamlParserFactory)
: base(xamlParserFactory)
{
}
/// <summary>
/// Gets the URI of the XAML file currently being loaded.
/// </summary>
/// <remarks>
/// TODO: Making this internal for now as I'm not sure that this is the correct
/// thing to do, but its needed by <see cref="StyleInclude"/> to get the URL of
/// the currently loading XAML file, as we can't use the OmniXAML parsing context
/// there. Maybe we need a way to inject OmniXAML context into the objects its
/// constructing?
/// </remarks>
internal static Uri UriContext => s_uriStack.Count > 0 ? s_uriStack.Peek() : null;
/// <summary>
/// Loads the XAML into a Avalonia component.
/// </summary>
/// <param name="obj">The object to load the XAML into.</param>
public static void Load(object obj)
{
Contract.Requires<ArgumentNullException>(obj != null);
var loader = new AvaloniaXamlLoader();
loader.Load(obj.GetType(), obj);
}
/// <summary>
/// Loads the XAML for a type.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(Type type, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(type != null);
// HACK: Currently Visual Studio is forcing us to change the extension of xaml files
// in certain situations, so we try to load .xaml and if that's not found we try .xaml.
// Ideally we'd be able to use .xaml everywhere
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{
throw new InvalidOperationException(
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?");
}
foreach (var uri in GetUrisFor(type))
{
if (assetLocator.Exists(uri))
{
using (var stream = assetLocator.Open(uri))
{
var initialize = rootInstance as ISupportInitialize;
initialize?.BeginInit();
return Load(stream, rootInstance, uri);
}
}
}
throw new FileNotFoundException("Unable to find view for " + type.FullName);
}
/// <summary>
/// Loads XAML from a URI.
/// </summary>
/// <param name="uri">The URI of the XAML file.</param>
/// <param name="baseUri">
/// A base URI to use if <paramref name="uri"/> is relative.
/// </param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(Uri uri, Uri baseUri = null, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(uri != null);
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{
throw new InvalidOperationException(
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?");
}
using (var stream = assetLocator.Open(uri, baseUri))
{
return Load(stream, rootInstance, uri);
}
}
/// <summary>
/// Loads XAML from a string.
/// </summary>
/// <param name="xaml">The string containing the XAML.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(string xaml, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(xaml != null);
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml)))
{
return Load(stream, rootInstance);
}
}
/// <summary>
/// Loads XAML from a stream.
/// </summary>
/// <param name="stream">The stream containing the XAML.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <param name="uri">The URI of the XAML</param>
/// <returns>The loaded object.</returns>
public object Load(Stream stream, object rootInstance = null, Uri uri = null)
{
try
{
if (uri != null)
{
s_uriStack.Push(uri);
}
var result = base.Load(stream, new Settings
{
RootInstance = rootInstance,
InstanceLifeCycleListener = s_lifeCycleListener,
ParsingContext = new Dictionary<string, object>
{
{ "Uri", uri }
}
});
var topLevel = result as TopLevel;
if (topLevel != null)
{
DelayedBinding.ApplyBindings(topLevel);
}
return result;
}
finally
{
if (uri != null)
{
s_uriStack.Pop();
}
}
}
private static AvaloniaParserFactory GetParserFactory()
{
if (s_parserFactory == null)
{
s_parserFactory = new AvaloniaParserFactory();
}
return s_parserFactory;
}
/// <summary>
/// Gets the URI for a type.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>The URI.</returns>
private static IEnumerable<Uri> GetUrisFor(Type type)
{
var asm = type.GetTypeInfo().Assembly.GetName().Name;
var typeName = type.FullName;
yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm);
yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm);
public static object Parse(string xaml)
=> new AvaloniaXamlLoader().Load(xaml);
}
public static T Parse<T>(string xaml)
=> (T)Parse(xaml);
}
}
}

215
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs

@ -0,0 +1,215 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Controls;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Markup.Xaml.PortableXaml;
using Avalonia.Platform;
using Portable.Xaml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
namespace Avalonia.Markup.Xaml
{
/// <summary>
/// Loads XAML for a avalonia application.
/// </summary>
public class AvaloniaXamlLoaderPortableXaml
{
private readonly AvaloniaXamlSchemaContext _context = GetContext();
private static AvaloniaXamlSchemaContext GetContext()
{
var result = AvaloniaLocator.Current.GetService<AvaloniaXamlSchemaContext>();
if (result == null)
{
result = AvaloniaXamlSchemaContext.Create();
AvaloniaLocator.CurrentMutable
.Bind<AvaloniaXamlSchemaContext>()
.ToConstant(result);
}
return result;
}
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
/// </summary>
public AvaloniaXamlLoaderPortableXaml()
{
}
/// <summary>
/// Loads the XAML into a Avalonia component.
/// </summary>
/// <param name="obj">The object to load the XAML into.</param>
public static void Load(object obj)
{
Contract.Requires<ArgumentNullException>(obj != null);
var loader = new AvaloniaXamlLoader();
loader.Load(obj.GetType(), obj);
}
/// <summary>
/// Loads the XAML for a type.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(Type type, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(type != null);
// HACK: Currently Visual Studio is forcing us to change the extension of xaml files
// in certain situations, so we try to load .xaml and if that's not found we try .xaml.
// Ideally we'd be able to use .xaml everywhere
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{
throw new InvalidOperationException(
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?");
}
foreach (var uri in GetUrisFor(type))
{
if (assetLocator.Exists(uri))
{
using (var stream = assetLocator.Open(uri))
{
var initialize = rootInstance as ISupportInitialize;
initialize?.BeginInit();
try
{
return Load(stream, rootInstance, uri);
}
finally
{
initialize?.EndInit();
}
}
}
}
throw new FileNotFoundException("Unable to find view for " + type.FullName);
}
/// <summary>
/// Loads XAML from a URI.
/// </summary>
/// <param name="uri">The URI of the XAML file.</param>
/// <param name="baseUri">
/// A base URI to use if <paramref name="uri"/> is relative.
/// </param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(Uri uri, Uri baseUri = null, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(uri != null);
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{
throw new InvalidOperationException(
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?");
}
using (var stream = assetLocator.Open(uri, baseUri))
{
return Load(stream, rootInstance, uri);
}
}
/// <summary>
/// Loads XAML from a string.
/// </summary>
/// <param name="xaml">The string containing the XAML.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <returns>The loaded object.</returns>
public object Load(string xaml, object rootInstance = null)
{
Contract.Requires<ArgumentNullException>(xaml != null);
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml)))
{
return Load(stream, rootInstance);
}
}
/// <summary>
/// Loads XAML from a stream.
/// </summary>
/// <param name="stream">The stream containing the XAML.</param>
/// <param name="rootInstance">
/// The optional instance into which the XAML should be loaded.
/// </param>
/// <param name="uri">The URI of the XAML</param>
/// <returns>The loaded object.</returns>
public object Load(Stream stream, object rootInstance = null, Uri uri = null)
{
var readerSettings = new XamlXmlReaderSettings()
{
BaseUri = uri,
LocalAssembly = rootInstance?.GetType().GetTypeInfo().Assembly
};
var reader = new XamlXmlReader(stream, _context, readerSettings);
object result = LoadFromReader(
reader,
AvaloniaXamlContext.For(readerSettings, rootInstance));
var topLevel = result as TopLevel;
if (topLevel != null)
{
DelayedBinding.ApplyBindings(topLevel);
}
return result;
}
internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null)
{
var writer = AvaloniaXamlObjectWriter.Create(
reader.SchemaContext,
context);
XamlServices.Transform(reader, writer);
return writer.Result;
}
internal static object LoadFromReader(XamlReader reader)
{
//return XamlServices.Load(reader);
return LoadFromReader(reader, null);
}
/// <summary>
/// Gets the URI for a type.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>The URI.</returns>
private static IEnumerable<Uri> GetUrisFor(Type type)
{
var asm = type.GetTypeInfo().Assembly.GetName().Name;
var typeName = type.FullName;
yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm);
yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm);
}
}
}

33
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaAttachableXamlMember.cs

@ -1,33 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Markup.Xaml.Data;
using OmniXaml;
using OmniXaml.Typing;
using System.Reflection;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaAttachableXamlMember : AttachableMember
{
public AvaloniaAttachableXamlMember(string name,
XamlType owner,
MethodInfo getter,
MethodInfo setter,
ITypeRepository xamlTypeRepository,
ITypeFeatureProvider featureProvider)
: base(name, getter, setter, xamlTypeRepository, featureProvider)
{
}
public override string ToString()
{
return "Avalonia Attachable XAML Member " + base.ToString();
}
protected override IMemberValuePlugin LookupXamlMemberValueConnector()
{
return new AvaloniaMemberValuePlugin(this);
}
}
}

58
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaContentPropertyProvider.cs

@ -1,58 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Glass;
using OmniXaml;
using OmniXaml.Builder;
using Avalonia.Metadata;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaContentPropertyProvider : IContentPropertyProvider
{
private readonly Dictionary<Type, string> _values = new Dictionary<Type, string>();
public string GetContentPropertyName(Type type)
{
string result;
if (!_values.TryGetValue(type, out result))
{
result = LookupContentProperty(type);
_values[type] = result;
}
return result;
}
private string LookupContentProperty(Type type)
{
var result = (from member in type.GetRuntimeProperties()
let att = member.GetCustomAttribute<ContentAttribute>()
where att != null
select member).FirstOrDefault();
return result?.Name;
}
void IAdd<ContentPropertyDefinition>.Add(ContentPropertyDefinition item)
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator<ContentPropertyDefinition> IEnumerable<ContentPropertyDefinition>.GetEnumerator()
{
throw new NotImplementedException();
}
}
}

31
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaLifeCycleListener.cs

@ -1,31 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaLifeCycleListener : IInstanceLifeCycleListener
{
public void OnAfterProperties(object instance)
{
}
public void OnAssociatedToParent(object instance)
{
}
public void OnBegin(object instance)
{
var isi = instance as ISupportInitialize;
isi?.BeginInit();
}
public void OnEnd(object instance)
{
var isi = instance as ISupportInitialize;
isi?.EndInit();
}
}
}

25
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaMemberValuePlugin.cs

@ -1,25 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml.TypeConversion;
using OmniXaml.Typing;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaMemberValuePlugin : MemberValuePlugin
{
private readonly MutableMember _xamlMember;
public AvaloniaMemberValuePlugin(MutableMember xamlMember)
: base(xamlMember)
{
_xamlMember = xamlMember;
}
public override void SetValue(object instance, object value, IValueContext valueContext)
{
PropertyAccessor.SetValue(instance, _xamlMember, value, valueContext);
}
}
}

181
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs

@ -1,181 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using OmniXaml.Builder;
using OmniXaml.Typing;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Styling;
using Glass.Core;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaNamespaceRegistry : INamespaceRegistry
{
private const string ClrNamespace = "clr-namespace:";
private const string AvaloniaNs = "https://github.com/avaloniaui";
private static readonly IEnumerable<Assembly> ForcedAssemblies = new[]
{
typeof(AvaloniaObject).GetTypeInfo().Assembly,
typeof(Control).GetTypeInfo().Assembly,
typeof(Style).GetTypeInfo().Assembly,
typeof(DataTemplate).GetTypeInfo().Assembly,
typeof(SolidColorBrush).GetTypeInfo().Assembly,
typeof(IValueConverter).GetTypeInfo().Assembly,
};
private List<ClrNamespace> _clrNamespaces = new List<ClrNamespace>();
private List<XamlNamespace> _namespaces = new List<XamlNamespace>();
private Dictionary<string, string> _prefixes = new Dictionary<string, string>();
private List<Assembly> _scanned = new List<Assembly>();
public AvaloniaNamespaceRegistry()
{
ScanAssemblies(ForcedAssemblies);
ScanNewAssemblies();
RegisterPrefix(new PrefixRegistration(string.Empty, AvaloniaNs));
}
public IEnumerable<PrefixRegistration> RegisteredPrefixes =>
_prefixes.Select(x => new PrefixRegistration(x.Key, x.Value));
public void AddNamespace(XamlNamespace xamlNamespace)
{
_namespaces.Add(xamlNamespace);
}
public Namespace GetNamespace(string name)
{
Namespace result;
if (!IsClrNamespace(name))
{
ScanNewAssemblies();
result = _namespaces.FirstOrDefault(x => x.Name == name);
if (result == null)
{
result = _namespaces.FirstOrDefault(x => x.Name == name);
}
}
else
{
var nsAndAssembly = ParseClrNameSpace(name);
result = _clrNamespaces.FirstOrDefault(x =>
x.Name == nsAndAssembly.Item1 &&
x.Assembly.GetName().Name == nsAndAssembly.Item2);
if (result == null)
{
var clr = CreateClrNamespace(name);
_clrNamespaces.Add(clr);
result = clr;
}
}
return result;
}
public Namespace GetNamespaceByPrefix(string prefix)
{
string uri;
if (_prefixes.TryGetValue(prefix, out uri))
{
return GetNamespace(uri);
}
return null;
}
public void RegisterPrefix(PrefixRegistration prefixRegistration)
{
_prefixes[prefixRegistration.Prefix] = prefixRegistration.Ns;
}
private static bool IsClrNamespace(string ns)
{
return ns.StartsWith(ClrNamespace);
}
private static ClrNamespace CreateClrNamespace(string formattedClrString)
{
var nsAndAssembly = ParseClrNameSpace(formattedClrString);
var assembly = GetAssembly(nsAndAssembly.Item2);
return new ClrNamespace(assembly, nsAndAssembly.Item1);
}
private static Tuple<string, string> ParseClrNameSpace(string clrNamespace)
{
var startOfNamespace = clrNamespace.IndexOf(":", StringComparison.Ordinal) + 1;
var endOfNamespace = clrNamespace.IndexOf(";", startOfNamespace, StringComparison.Ordinal);
if (endOfNamespace < 0)
{
endOfNamespace = clrNamespace.Length - startOfNamespace;
}
var ns = clrNamespace.Substring(startOfNamespace, endOfNamespace - startOfNamespace);
var remainingPartStart = startOfNamespace + ns.Length + 1;
var remainingPartLenght = clrNamespace.Length - remainingPartStart;
var assemblyPart = clrNamespace.Substring(remainingPartStart, remainingPartLenght);
return Tuple.Create(ns, assemblyPart.Dicotomize('=').Item2);
}
private static Assembly GetAssembly(string assemblyName)
{
return Assembly.Load(new AssemblyName(assemblyName));
}
private void ScanAssemblies(IEnumerable<Assembly> assemblies)
{
foreach (var assembly in assemblies)
{
var namespaces = assembly.GetCustomAttributes<XmlnsDefinitionAttribute>()
.Select(x => new { x.XmlNamespace, x.ClrNamespace })
.GroupBy(x => x.XmlNamespace);
foreach (var nsa in namespaces)
{
var xamlNamespace = _namespaces.FirstOrDefault(x => x.Name == nsa.Key);
if (xamlNamespace == null)
{
xamlNamespace = new XamlNamespace(nsa.Key);
_namespaces.Add(xamlNamespace);
}
var clrNamespaces = nsa.Select(x => x.ClrNamespace);
xamlNamespace.Addresses.Add(new ConfiguredAssemblyWithNamespaces(assembly, clrNamespaces));
}
_scanned.Add(assembly);
}
}
private void ScanNewAssemblies()
{
IEnumerable<Assembly> assemblies = AvaloniaLocator.Current
.GetService<IRuntimePlatform>()
?.GetLoadedAssemblies();
if (assemblies != null)
{
assemblies = assemblies.Except(_scanned);
ScanAssemblies(assemblies);
}
}
}
}

79
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaObjectAssembler.cs

@ -1,79 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
using OmniXaml.ObjectAssembler;
using OmniXaml.ObjectAssembler.Commands;
using OmniXaml.TypeConversion;
using Avalonia.Markup.Xaml.Templates;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaObjectAssembler : IObjectAssembler
{
private readonly TemplateHostingObjectAssembler objectAssembler;
private readonly ObjectAssembler assembler;
public AvaloniaObjectAssembler(
IRuntimeTypeSource typeSource,
ITopDownValueContext topDownValueContext,
Settings settings = null)
{
var mapping = new DeferredLoaderMapping();
mapping.Map<Template>(x => x.Content, new TemplateLoader());
mapping.Map<ControlTemplate>(x => x.Content, new TemplateLoader());
mapping.Map<DataTemplate>(x => x.Content, new TemplateLoader());
mapping.Map<FocusAdornerTemplate>(x => x.Content, new TemplateLoader());
mapping.Map<TreeDataTemplate>(x => x.Content, new TemplateLoader());
mapping.Map<ItemsPanelTemplate>(x => x.Content, new TemplateLoader());
var parsingDictionary = GetDictionary(settings);
var valueContext = new ValueContext(typeSource, topDownValueContext, parsingDictionary);
assembler = new ObjectAssembler(typeSource, valueContext, settings);
objectAssembler = new TemplateHostingObjectAssembler(assembler, mapping);
}
public object Result => objectAssembler.Result;
public EventHandler<XamlSetValueEventArgs> XamlSetValueHandler { get; set; }
public IRuntimeTypeSource TypeSource => assembler.TypeSource;
public ITopDownValueContext TopDownValueContext => assembler.TopDownValueContext;
public IInstanceLifeCycleListener LifecycleListener
{
get { throw new NotImplementedException(); }
}
public void Process(Instruction node)
{
objectAssembler.Process(node);
}
public void OverrideInstance(object instance)
{
objectAssembler.OverrideInstance(instance);
}
private static IReadOnlyDictionary<string, object> GetDictionary(Settings settings)
{
IReadOnlyDictionary<string, object> dict;
if (settings != null)
{
dict = settings.ParsingContext;
}
else
{
dict = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
}
return dict;
}
}
}

41
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaParserFactory.cs

@ -1,41 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using OmniXaml;
using OmniXaml.ObjectAssembler;
using OmniXaml.Parsers.Parser;
using OmniXaml.Parsers.ProtoParser;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaParserFactory : IParserFactory
{
private readonly IRuntimeTypeSource runtimeTypeSource;
public AvaloniaParserFactory()
: this(new TypeFactory())
{
}
public AvaloniaParserFactory(ITypeFactory typeFactory)
{
runtimeTypeSource = new AvaloniaRuntimeTypeSource(typeFactory);
}
public IParser Create(Settings settings)
{
var xamlInstructionParser = new OrderAwareInstructionParser(new InstructionParser(runtimeTypeSource));
IObjectAssembler objectAssembler = new AvaloniaObjectAssembler(
runtimeTypeSource,
new TopDownValueContext(),
settings);
var phaseParserKit = new PhaseParserKit(
new ProtoInstructionParser(runtimeTypeSource),
xamlInstructionParser,
objectAssembler);
return new XmlParser(phaseParserKit);
}
}
}

91
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaRuntimeTypeSource.cs

@ -1,91 +0,0 @@
namespace Avalonia.Markup.Xaml.Context
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Collections;
using Controls;
using Controls.Primitives;
using Controls.Templates;
using Converters;
using Data;
using Glass;
using Input;
using Media;
using Media.Imaging;
using Metadata;
using OmniXaml;
using OmniXaml.Builder;
using OmniXaml.TypeConversion;
using OmniXaml.Typing;
using Avalonia.Styling;
using Platform;
using Templates;
public class AvaloniaRuntimeTypeSource : IRuntimeTypeSource
{
private readonly RuntimeTypeSource inner;
public AvaloniaRuntimeTypeSource(ITypeFactory typeFactory)
{
var namespaceRegistry = new AvaloniaNamespaceRegistry();
var featureProvider = new AvaloniaTypeFeatureProvider();
var typeRepository = new AvaloniaTypeRepository(namespaceRegistry, typeFactory, featureProvider);
inner = new RuntimeTypeSource(typeRepository, namespaceRegistry);
}
public Namespace GetNamespace(string name)
{
return inner.GetNamespace(name);
}
public Namespace GetNamespaceByPrefix(string prefix)
{
return inner.GetNamespaceByPrefix(prefix);
}
public void RegisterPrefix(PrefixRegistration prefixRegistration)
{
inner.RegisterPrefix(prefixRegistration);
}
public void AddNamespace(XamlNamespace xamlNamespace)
{
inner.AddNamespace(xamlNamespace);
}
public IEnumerable<PrefixRegistration> RegisteredPrefixes => inner.RegisteredPrefixes;
public XamlType GetByType(Type type)
{
return inner.GetByType(type);
}
public XamlType GetByQualifiedName(string qualifiedName)
{
return inner.GetByQualifiedName(qualifiedName);
}
public XamlType GetByPrefix(string prefix, string typeName)
{
return inner.GetByPrefix(prefix, typeName);
}
public XamlType GetByFullAddress(XamlTypeName xamlTypeName)
{
return inner.GetByFullAddress(xamlTypeName);
}
public Member GetMember(PropertyInfo propertyInfo)
{
return inner.GetMember(propertyInfo);
}
public AttachableMember GetAttachableMember(string name, MethodInfo getter, MethodInfo setter)
{
return inner.GetAttachableMember(name, getter, setter);
}
}
}

180
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs

@ -1,180 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Markup.Xaml.Converters;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Metadata;
using Avalonia.Styling;
using OmniXaml;
using OmniXaml.Builder;
using OmniXaml.TypeConversion;
using OmniXaml.TypeConversion.BuiltInConverters;
using OmniXaml.Typing;
using OmniMetadata = OmniXaml.Typing.Metadata;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaTypeFeatureProvider : ITypeFeatureProvider
{
private Dictionary<Type, OmniMetadata> _metadata =
new Dictionary<Type, OmniMetadata>();
private Dictionary<Type, TypeConverterRegistration> _typeConverters =
new Dictionary<Type, TypeConverterRegistration>();
public IEnumerable<TypeConverterRegistration> TypeConverters => _typeConverters.Values;
public AvaloniaTypeFeatureProvider()
{
RegisterTypeConverters();
}
public string GetContentPropertyName(Type type)
{
return GetMetadata(type)?.ContentProperty;
}
public OmniMetadata GetMetadata(Type type)
{
OmniMetadata result;
if (!_metadata.TryGetValue(type, out result))
{
result = LoadMetadata(type);
_metadata.Add(type, result);
}
return result;
}
public ITypeConverter GetTypeConverter(Type type)
{
TypeConverterRegistration result;
_typeConverters.TryGetValue(type, out result);
return result?.TypeConverter;
}
public void RegisterMetadata(Type type, OmniMetadata metadata)
{
_metadata.Add(type, metadata);
}
public void RegisterTypeConverter(Type type, ITypeConverter converter)
{
_typeConverters.Add(type, new TypeConverterRegistration(type, converter));
}
private static OmniMetadata LoadMetadata(Type type)
{
return new OmniMetadata
{
ContentProperty = GetContentProperty(type),
PropertyDependencies = GetPropertyDependencies(type),
RuntimePropertyName = type.GetRuntimeProperty("Name")?.Name,
};
}
private static string GetContentProperty(Type type)
{
while (type != null)
{
var properties = type.GetTypeInfo().DeclaredProperties
.Where(x => x.GetCustomAttribute<ContentAttribute>() != null);
string result = null;
foreach (var property in properties)
{
if (result != null)
{
throw new Exception($"Content property defined more than once on {type}.");
}
result = property.Name;
}
if (result != null)
{
return result;
}
type = type.GetTypeInfo().BaseType;
}
return null;
}
private static DependencyRegistrations GetPropertyDependencies(Type type)
{
var result = new List<DependencyRegistration>();
while (type != null)
{
var registrations = type.GetTypeInfo().DeclaredProperties
.Select(x => new
{
Property = x.Name,
Attributes = x.GetCustomAttributes<DependsOnAttribute>(),
})
.Where(x => x.Attributes.Any())
.SelectMany(x => x.Attributes.Select(y => new DependencyRegistration(x.Property, y.Name)));
result.AddRange(registrations);
type = type.GetTypeInfo().BaseType;
}
return result.Count > 0 ? new DependencyRegistrations(result) : null;
}
private void RegisterTypeConverters()
{
// HACK: For now these are hard-coded. Hopefully when the .NET Standard Platform
// is available we can use the System.ComponentModel.TypeConverters so don't want to
// spend time for now inventing a mechanism to register type converters if it's all
// going to change.
RegisterTypeConverter(typeof(string), new StringTypeConverter());
RegisterTypeConverter(typeof(int), new IntTypeConverter());
RegisterTypeConverter(typeof(long), new IntTypeConverter());
RegisterTypeConverter(typeof(short), new IntTypeConverter());
RegisterTypeConverter(typeof(double), new DoubleTypeConverter());
RegisterTypeConverter(typeof(float), new IntTypeConverter());
RegisterTypeConverter(typeof(bool), new BooleanConverter());
RegisterTypeConverter(typeof(Type), new TypeTypeConverter());
RegisterTypeConverter(typeof(IBitmap), new BitmapTypeConverter());
RegisterTypeConverter(typeof(IBrush), new BrushTypeConverter());
RegisterTypeConverter(typeof(Color), new ColorTypeConverter());
RegisterTypeConverter(typeof(Classes), new ClassesTypeConverter());
RegisterTypeConverter(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter());
RegisterTypeConverter(typeof(DateTime), new DateTimeTypeConverter());
RegisterTypeConverter(typeof(Geometry), new GeometryTypeConverter());
RegisterTypeConverter(typeof(GridLength), new GridLengthTypeConverter());
RegisterTypeConverter(typeof(KeyGesture), new KeyGestureConverter());
RegisterTypeConverter(typeof(AvaloniaList<double>), new AvaloniaListTypeConverter<double>());
RegisterTypeConverter(typeof(IMemberSelector), new MemberSelectorTypeConverter());
RegisterTypeConverter(typeof(Point), new PointTypeConverter());
RegisterTypeConverter(typeof(IList<Point>), new PointsListTypeConverter());
RegisterTypeConverter(typeof(AvaloniaProperty), new AvaloniaPropertyTypeConverter());
RegisterTypeConverter(typeof(RelativePoint), new RelativePointTypeConverter());
RegisterTypeConverter(typeof(RelativeRect), new RelativeRectTypeConverter());
RegisterTypeConverter(typeof(RowDefinitions), new RowDefinitionsTypeConverter());
RegisterTypeConverter(typeof(Size), new SizeTypeConverter());
RegisterTypeConverter(typeof(Selector), new SelectorTypeConverter());
RegisterTypeConverter(typeof(SolidColorBrush), new BrushTypeConverter());
RegisterTypeConverter(typeof(Thickness), new ThicknessTypeConverter());
RegisterTypeConverter(typeof(TimeSpan), new TimeSpanTypeConverter());
RegisterTypeConverter(typeof(Uri), new UriTypeConverter());
RegisterTypeConverter(typeof(Cursor), new CursorTypeConverter());
RegisterTypeConverter(typeof(WindowIcon), new IconTypeConverter());
RegisterTypeConverter(typeof(FontWeight), new FontWeightConverter());
}
}
}

28
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeRepository.cs

@ -1,28 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
using OmniXaml.Typing;
using Glass.Core;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaTypeRepository : TypeRepository
{
private readonly ITypeFactory _typeFactory;
public AvaloniaTypeRepository(INamespaceRegistry xamlNamespaceRegistry,
ITypeFactory typeFactory,
ITypeFeatureProvider featureProvider) : base(xamlNamespaceRegistry, typeFactory, featureProvider)
{
_typeFactory = typeFactory;
}
public override XamlType GetByType(Type type)
{
Guard.ThrowIfNull(type, nameof(type));
return new AvaloniaXamlType(type, this, _typeFactory, FeatureProvider);
}
}
}

126
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaWiringContext.cs

@ -1,126 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reflection;
using Glass;
using OmniXaml;
using OmniXaml.Builder;
using OmniXaml.TypeConversion;
using OmniXaml.Typing;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Markup.Xaml.Converters;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Styling;
using System.Collections.Generic;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaWiringContext : WiringContext
{
private const string AvaloniaNs = "https://github.com/avaloniaui";
public AvaloniaWiringContext(ITypeFactory typeFactory)
: this(typeFactory, new TypeFeatureProvider(GetContentPropertyProvider(), GetConverterProvider()))
{
}
public AvaloniaWiringContext(ITypeFactory typeFactory, TypeFeatureProvider featureProvider)
: base(CreateTypeContext(typeFactory, featureProvider), featureProvider)
{
}
private static ITypeContext CreateTypeContext(ITypeFactory typeFactory, TypeFeatureProvider featureProvider)
{
var xamlNamespaceRegistry = CreateXamlNamespaceRegistry();
var typeRepository = new AvaloniaTypeRepository(xamlNamespaceRegistry, typeFactory, featureProvider);
typeRepository.RegisterMetadata(new GenericMetadata<Visual>().WithRuntimeNameProperty(d => d.Name));
typeRepository.RegisterMetadata(new GenericMetadata<Setter>().WithMemberDependency(x => x.Value, x => x.Property));
typeRepository.RegisterMetadata(
new GenericMetadata<SelectingItemsControl>()
.WithMemberDependency(x => x.SelectedIndex, x => x.Items)
.WithMemberDependency(x => x.SelectedItem, x => x.Items));
return new TypeContext(typeRepository, xamlNamespaceRegistry, typeFactory);
}
private static XamlNamespaceRegistry CreateXamlNamespaceRegistry()
{
var xamlNamespaceRegistry = new XamlNamespaceRegistry();
var forcedAssemblies = new[]
{
typeof(Binding),
typeof(Control),
typeof(IValueConverter),
typeof(Style),
}.Select(t => t.GetTypeInfo().Assembly);
foreach (var nsa in
forcedAssemblies
.Concat(AvaloniaLocator.Current.GetService<IPclPlatformWrapper>().GetLoadedAssemblies())
.Distinct()
.SelectMany(asm
=> asm.GetCustomAttributes<XmlnsDefinitionAttribute>().Select(attr => new {asm, attr}))
.GroupBy(entry => entry.attr.XmlNamespace))
{
var def = XamlNamespace.Map(nsa.Key)
.With(nsa.GroupBy(x => x.asm).Select(
a => Route.Assembly(a.Key)
.WithNamespaces(a.Select(entry => entry.attr.ClrNamespace).ToList())
));
xamlNamespaceRegistry.AddNamespace(def);
}
xamlNamespaceRegistry.RegisterPrefix(new PrefixRegistration(string.Empty, AvaloniaNs));
return xamlNamespaceRegistry;
}
private static ITypeConverterProvider GetConverterProvider()
{
var typeConverterProvider = new TypeConverterProvider();
var converters = new[]
{
new TypeConverterRegistration(typeof(IBitmap), new BitmapTypeConverter()),
new TypeConverterRegistration(typeof(Brush), new BrushTypeConverter()),
new TypeConverterRegistration(typeof(Color), new ColorTypeConverter()),
new TypeConverterRegistration(typeof(Classes), new ClassesTypeConverter()),
new TypeConverterRegistration(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()),
new TypeConverterRegistration(typeof(Geometry), new GeometryTypeConverter()),
new TypeConverterRegistration(typeof(GridLength), new GridLengthTypeConverter()),
new TypeConverterRegistration(typeof(KeyGesture), new KeyGestureConverter()),
new TypeConverterRegistration(typeof(AvaloniaList<double>), new AvaloniaListTypeConverter<double>()),
new TypeConverterRegistration(typeof(IMemberSelector), new MemberSelectorTypeConverter()),
new TypeConverterRegistration(typeof(Point), new PointTypeConverter()),
new TypeConverterRegistration(typeof(IList<Point>), new PointsListTypeConverter()),
new TypeConverterRegistration(typeof(AvaloniaProperty), new AvaloniaPropertyTypeConverter()),
new TypeConverterRegistration(typeof(RelativePoint), new RelativePointTypeConverter()),
new TypeConverterRegistration(typeof(RelativeRect), new RelativeRectTypeConverter()),
new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()),
new TypeConverterRegistration(typeof(Selector), new SelectorTypeConverter()),
new TypeConverterRegistration(typeof(Thickness), new ThicknessTypeConverter()),
new TypeConverterRegistration(typeof(TimeSpan), new TimeSpanTypeConverter()),
new TypeConverterRegistration(typeof(Uri), new UriTypeConverter()),
new TypeConverterRegistration(typeof(Cursor), new CursorTypeConverter())
};
typeConverterProvider.AddAll(converters);
return typeConverterProvider;
}
private static IContentPropertyProvider GetContentPropertyProvider()
{
return new AvaloniaContentPropertyProvider();
}
}
}

31
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaXamlMember.cs

@ -1,31 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Markup.Xaml.Data;
using OmniXaml;
using OmniXaml.Typing;
using System;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaXamlMember : Member
{
public AvaloniaXamlMember(string name,
XamlType owner,
ITypeRepository xamlTypeRepository,
ITypeFeatureProvider featureProvider)
: base(name, owner, xamlTypeRepository, featureProvider)
{
}
protected override IMemberValuePlugin LookupXamlMemberValueConnector()
{
return new AvaloniaMemberValuePlugin(this);
}
public override string ToString()
{
return "Avalonia XAML Member " + base.ToString();
}
}
}

61
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaXamlType.cs

@ -1,61 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reflection;
using OmniXaml;
using OmniXaml.Typing;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.Context
{
public class AvaloniaXamlType : XamlType
{
public AvaloniaXamlType(Type type,
ITypeRepository typeRepository,
ITypeFactory typeFactory,
ITypeFeatureProvider featureProvider) : base(type, typeRepository, typeFactory, featureProvider)
{
}
public override OmniXaml.INameScope GetNamescope(object instance)
{
var result = instance as OmniXaml.INameScope;
if (result == null)
{
var control = instance as Control;
if (control != null)
{
var avaloniaNs = (instance as Avalonia.Controls.INameScope) ?? NameScope.GetNameScope(control);
if (avaloniaNs != null)
{
result = new NameScopeWrapper(avaloniaNs);
}
}
}
return result;
}
protected override Member LookupMember(string name)
{
return new AvaloniaXamlMember(name, this, TypeRepository, FeatureProvider);
}
protected override AttachableMember LookupAttachableMember(string name)
{
// OmniXAML seems to require a getter and setter even though we don't use them.
var getter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Get" + name);
var setter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Set" + name);
return new AvaloniaAttachableXamlMember(name, this, getter, setter, TypeRepository, FeatureProvider);
}
public override string ToString()
{
return "Avalonia XAML Type " + base.ToString();
}
}
}

30
src/Markup/Avalonia.Markup.Xaml/Context/NameScopeWrapper.cs

@ -1,30 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Avalonia.Markup.Xaml.Context
{
internal class NameScopeWrapper : OmniXaml.INameScope
{
private readonly Avalonia.Controls.INameScope _inner;
public NameScopeWrapper(Avalonia.Controls.INameScope inner)
{
_inner = inner;
}
public object Find(string name)
{
return _inner.Find(name);
}
public void Register(string name, object scopedElement)
{
_inner.Register(name, scopedElement);
}
public void Unregister(string name)
{
_inner.Unregister(name);
}
}
}

174
src/Markup/Avalonia.Markup.Xaml/Context/PropertyAccessor.cs

@ -1,174 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using OmniXaml.ObjectAssembler;
using OmniXaml.TypeConversion;
using OmniXaml.Typing;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Styling;
namespace Avalonia.Markup.Xaml.Context
{
internal static class PropertyAccessor
{
public static void SetValue(
object instance,
MutableMember member,
object value,
IValueContext context)
{
var avaloniaProperty = FindAvaloniaProperty(instance, member);
if (value is IBinding)
{
SetBinding(instance, member, avaloniaProperty, context, (IBinding)value);
}
else if (avaloniaProperty != null)
{
((AvaloniaObject)instance).SetValue(avaloniaProperty, value);
}
else if (instance is Setter && member.Name == "Value")
{
// TODO: Make this more generic somehow.
var setter = (Setter)instance;
var targetType = setter.Property.PropertyType;
var xamlType = member.TypeRepository.GetByType(targetType);
var convertedValue = default(object);
if (CommonValueConversion.TryConvert(value, xamlType, context, out convertedValue))
{
SetClrProperty(instance, member, convertedValue);
}
}
else
{
SetClrProperty(instance, member, value);
}
}
private static AvaloniaProperty FindAvaloniaProperty(object instance, MutableMember member)
{
var registry = AvaloniaPropertyRegistry.Instance;
var attached = member as AvaloniaAttachableXamlMember;
var target = instance as AvaloniaObject;
if (target == null)
{
return null;
}
if (attached == null)
{
return registry.FindRegistered(target, member.Name);
}
else
{
var ownerType = attached.DeclaringType.UnderlyingType;
RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
return registry.GetRegistered(target)
.Where(x => x.OwnerType == ownerType && x.Name == attached.Name)
.FirstOrDefault();
}
}
private static void SetBinding(
object instance,
MutableMember member,
AvaloniaProperty property,
IValueContext context,
IBinding binding)
{
if (!(AssignBinding(instance, member, binding) ||
ApplyBinding(instance, property, context, binding)))
{
throw new InvalidOperationException(
$"Cannot assign to '{member.Name}' on '{instance.GetType()}");
}
}
private static void SetClrProperty(object instance, MutableMember member, object value)
{
if (member.IsAttachable)
{
member.Setter.Invoke(null, new[] { instance, value });
}
else
{
member.Setter.Invoke(instance, new[] { value });
}
}
private static bool AssignBinding(object instance, MutableMember member, IBinding binding)
{
var property = instance.GetType()
.GetRuntimeProperties()
.FirstOrDefault(x => x.Name == member.Name);
if (property?.GetCustomAttribute<AssignBindingAttribute>() != null)
{
property.SetValue(instance, binding);
return true;
}
return false;
}
private static bool ApplyBinding(
object instance,
AvaloniaProperty property,
IValueContext context,
IBinding binding)
{
if (property == null)
{
return false;
}
var control = instance as IControl;
if (control != null)
{
if (property != Control.DataContextProperty)
{
DelayedBinding.Add(control, property, binding);
}
else
{
control.Bind(property, binding);
}
}
else
{
// The target is not a control, so we need to find an anchor that will let us look
// up named controls and style resources. First look for the closest IControl in
// the TopDownValueContext.
object anchor = context.TopDownValueContext.StoredInstances
.Select(x => x.Instance)
.OfType<IControl>()
.LastOrDefault();
// If a control was not found, then try to find the highest-level style as the XAML
// file could be a XAML file containing only styles.
if (anchor == null)
{
anchor = context.TopDownValueContext.StoredInstances
.Select(x => x.Instance)
.OfType<IStyle>()
.FirstOrDefault();
}
((IAvaloniaObject)instance).Bind(property, binding, anchor);
}
return true;
}
}
}

21
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaListTypeConverter.cs

@ -3,26 +3,22 @@
using System;
using System.Globalization;
using System.Linq;
using OmniXaml.TypeConversion;
using Avalonia.Collections;
using Avalonia.Utilities;
namespace Avalonia.Markup.Xaml.Converters
{
public class AvaloniaListTypeConverter<T> : ITypeConverter
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class AvaloniaListTypeConverter<T> : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var result = new AvaloniaList<T>();
var values = ((string)value).Split(',');
@ -43,10 +39,5 @@ namespace Avalonia.Markup.Xaml.Converters
return result;
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

44
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

@ -4,53 +4,52 @@
using System;
using System.Globalization;
using System.Linq;
using OmniXaml;
using OmniXaml.TypeConversion;
using Avalonia.Styling;
namespace Avalonia.Markup.Xaml.Converters
{
public class AvaloniaPropertyTypeConverter : ITypeConverter
using Avalonia.Styling;
using Portable.Xaml;
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
using Portable.Xaml.Markup;
public class AvaloniaPropertyTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var s = (string)value;
string typeName;
string propertyName;
Type type;
Type type = null;
ParseProperty(s, out typeName, out propertyName);
if (typeName == null)
{
var styleType = context.TypeRepository.GetByType(typeof(Style));
var style = (Style)context.TopDownValueContext.GetLastInstance(styleType);
type = style.Selector?.TargetType;
var style = context.GetFirstAmbientValue<Style>();
type = style?.Selector?.TargetType;
if (type == null)
{
throw new ParseException(
throw new Exception(
"Could not determine the target type. Please fully qualify the property name.");
}
}
else
{
type = context.TypeRepository.GetByQualifiedName(typeName)?.UnderlyingType;
var typeResolver = context.GetService<IXamlTypeResolver>();
type = typeResolver.Resolve(typeName);
if (type == null)
{
throw new ParseException($"Could not find type '{typeName}'.");
throw new Exception($"Could not find type '{typeName}'.");
}
}
@ -61,18 +60,13 @@ namespace Avalonia.Markup.Xaml.Converters
if (property == null)
{
throw new ParseException(
throw new Exception(
$"Could not find AvaloniaProperty '{type.Name}.{propertyName}'.");
}
return property;
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
private void ParseProperty(string s, out string typeName, out string propertyName)
{
var split = s.Split('.');
@ -89,7 +83,7 @@ namespace Avalonia.Markup.Xaml.Converters
}
else
{
throw new ParseException($"Invalid property name: '{s}'.");
throw new Exception($"Invalid property name: '{s}'.");
}
}
}

31
src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs

@ -3,50 +3,35 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace Avalonia.Markup.Xaml.Converters
{
public class BitmapTypeConverter : ITypeConverter
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class BitmapTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var uri = new Uri((string)value, UriKind.RelativeOrAbsolute);
var baseUri = GetBaseUri(context);
var scheme = uri.IsAbsoluteUri ? uri.Scheme : "file";
switch (scheme)
{
case "file":
return new Bitmap((string)value);
default:
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
return new Bitmap(assets.Open(uri, baseUri));
return new Bitmap(assets.Open(uri, context.GetBaseUri()));
}
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
private Uri GetBaseUri(IValueContext context)
{
object result;
context.ParsingDictionary.TryGetValue("Uri", out result);
return result as Uri;
}
}
}

21
src/Markup/Avalonia.Markup.Xaml/Converters/BrushTypeConverter.cs

@ -3,31 +3,24 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Media;
namespace Avalonia.Markup.Xaml.Converters
{
public class BrushTypeConverter : ITypeConverter
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class BrushTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Brush.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

20
src/Markup/Avalonia.Markup.Xaml/Converters/ClassesTypeConverter.cs

@ -3,32 +3,20 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Controls;
using Avalonia.Styling;
using System.ComponentModel;
namespace Avalonia.Markup.Xaml.Converters
{
public class ClassesTypeConverter : ITypeConverter
public class ClassesTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new Classes(((string)value).Split(' '));
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

21
src/Markup/Avalonia.Markup.Xaml/Converters/ColorTypeConverter.cs

@ -3,31 +3,24 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Media;
using System.ComponentModel;
namespace Avalonia.Markup.Xaml.Converters
{
public class ColorTypeConverter : ITypeConverter
public class ColorTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Color.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs

@ -3,31 +3,22 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.Converters
{
public class ColumnDefinitionsTypeConverter : ITypeConverter
using System.ComponentModel;
public class ColumnDefinitionsTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new ColumnDefinitions((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/Converters/CursorTypeConverter.cs

@ -3,34 +3,23 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace Avalonia.Markup.Xaml.Converters
{
public class CursorTypeConverter : ITypeConverter
using System.ComponentModel;
public class CursorTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var cursor = (StandardCursorType)Enum.Parse(typeof (StandardCursorType), ((string) value).Trim(), true);
var cursor = (StandardCursorType)Enum.Parse(typeof(StandardCursorType), ((string)value).Trim(), true);
return new Cursor(cursor);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

58
src/Markup/Avalonia.Markup.Xaml/Converters/DateTimeTypeConverter.cs

@ -1,58 +0,0 @@
using OmniXaml.TypeConversion;
using System;
using System.Globalization;
namespace Avalonia.Markup.Xaml.Converters
{
public class DateTimeTypeConverter : ITypeConverter
{
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
{
if (culture == null)
{
throw new ArgumentNullException("culture");
}
if (value == null)
{
throw new ArgumentNullException("value");
}
DateTimeFormatInfo dateTimeFormatInfo = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
DateTime d = DateTime.ParseExact(value.ToString(), dateTimeFormatInfo.ShortDatePattern, culture);
return d;
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (culture == null)
{
throw new ArgumentNullException("culture");
}
DateTime? d = value as DateTime?;
if (!d.HasValue || destinationType != typeof(string))
{
throw new NotSupportedException();
}
DateTimeFormatInfo dateTimeFormatInfo = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
return d.Value.ToString(dateTimeFormatInfo.ShortDatePattern, culture);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return destinationType == typeof(string);
}
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string);
}
}
}

39
src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs

@ -1,39 +0,0 @@
namespace Avalonia.Markup.Xaml.Converters
{
using Avalonia.Media;
using OmniXaml.TypeConversion;
using System;
using System.Globalization;
public class FontWeightConverter : ITypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
{
FontWeight result;
if (Enum.TryParse(value as string, out result))
{
return result;
}
else
{
throw new ArgumentException("unable to convert parameter to FontWeight");
}
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

28
src/Markup/Avalonia.Markup.Xaml/Converters/GeometryTypeConverter.cs

@ -1,30 +1,24 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Globalization;
using Avalonia.Media;
namespace Avalonia.Markup.Xaml.Converters
{
using System;
using System.Globalization;
using Media;
using OmniXaml.TypeConversion;
using System.ComponentModel;
public class GeometryTypeConverter : ITypeConverter
public class GeometryTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return StreamGeometry.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/GridLengthTypeConverter.cs

@ -3,31 +3,22 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.Converters
{
public class GridLengthTypeConverter : ITypeConverter
using System.ComponentModel;
public class GridLengthTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return GridLength.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

51
src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs

@ -1,70 +1,55 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using OmniXaml.TypeConversion;
using System;
using System.Globalization;
namespace Avalonia.Markup.Xaml.Converters
{
class IconTypeConverter : ITypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string) || typeof(IBitmap).GetTypeInfo().IsAssignableFrom(sourceType.GetTypeInfo());
}
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public bool CanConvertTo(IValueContext context, Type destinationType)
public class IconTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return false;
return sourceType == typeof(string);
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var path = value as string;
if (path != null)
{
return CreateIconFromPath(context, path);
return CreateIconFromPath(context, path);
}
var bitmap = value as IBitmap;
if (bitmap != null)
{
return new WindowIcon(bitmap);
}
throw new NotSupportedException();
}
private WindowIcon CreateIconFromPath(IValueContext context, string path)
private WindowIcon CreateIconFromPath(ITypeDescriptorContext context, string path)
{
var uri = new Uri(path, UriKind.RelativeOrAbsolute);
var baseUri = GetBaseUri(context);
var scheme = uri.IsAbsoluteUri ? uri.Scheme : "file";
switch (scheme)
{
case "file":
return new WindowIcon(path);
default:
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
return new WindowIcon(assets.Open(uri, baseUri));
return new WindowIcon(assets.Open(uri, context.GetBaseUri()));
}
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
private Uri GetBaseUri(IValueContext context)
{
object result;
context.ParsingDictionary.TryGetValue("Uri", out result);
return result as Uri;
}
}
}

22
src/Markup/Avalonia.Markup.Xaml/Converters/KeyGestureConverter.cs

@ -1,30 +1,24 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Input;
namespace Avalonia.Markup.Xaml.Converters
{
class KeyGestureConverter : ITypeConverter
using System.ComponentModel;
public class KeyGestureConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return KeyGesture.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/MemberSelectorTypeConverter.cs

@ -3,34 +3,25 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Markup.Xaml.Templates;
namespace Avalonia.Markup.Xaml.Converters
{
public class MemberSelectorTypeConverter : ITypeConverter
using System.ComponentModel;
public class MemberSelectorTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new MemberSelector
{
MemberName = (string)value,
};
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/PointTypeConverter.cs

@ -3,30 +3,21 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class PointTypeConverter : ITypeConverter
using System.ComponentModel;
public class PointTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Point.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

20
src/Markup/Avalonia.Markup.Xaml/Converters/PointsListTypeConverter.cs

@ -4,23 +4,19 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class PointsListTypeConverter : ITypeConverter
using System.ComponentModel;
public class PointsListTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string strValue = (string)value;
string[] pointStrs = strValue.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
@ -29,12 +25,8 @@ namespace Avalonia.Markup.Xaml.Converters
{
result.Add(Point.Parse(pointStr, culture));
}
return result;
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
return result;
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/RelativePointTypeConverter.cs

@ -3,30 +3,21 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class RelativePointTypeConverter : ITypeConverter
using System.ComponentModel;
public class RelativePointTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return RelativePoint.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/RelativeRectTypeConverter.cs

@ -3,30 +3,21 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class RelativeRectTypeConverter : ITypeConverter
using System.ComponentModel;
public class RelativeRectTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return RelativeRect.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs

@ -3,31 +3,22 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.Converters
{
public class RowDefinitionsTypeConverter : ITypeConverter
using System.ComponentModel;
public class RowDefinitionsTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return new RowDefinitions((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

21
src/Markup/Avalonia.Markup.Xaml/Converters/SelectorTypeConverter.cs

@ -3,32 +3,25 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Markup.Xaml.Parsers;
namespace Avalonia.Markup.Xaml.Converters
{
public class SelectorTypeConverter : ITypeConverter
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class SelectorTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return false;
}
var parser = new SelectorParser((t, ns) => context.ResolveType(ns, t));
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
{
var parser = new SelectorParser((t, ns) => context.TypeRepository.GetByPrefix(ns ?? "", t).UnderlyingType);
return parser.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

49
src/Markup/Avalonia.Markup.Xaml/Converters/SetterValueTypeConverter.cs

@ -0,0 +1,49 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Styling;
using Portable.Xaml;
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
using Portable.Xaml.Markup;
using System;
using System.Globalization;
namespace Avalonia.Markup.Xaml.Converters
{
public class SetterValueTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
object setter = context.GetService<IProvideValueTarget>().TargetObject;
var schemaContext = context.GetService<IXamlSchemaContextProvider>().SchemaContext;
return ConvertSetterValue(schemaContext, (setter as Setter), value);
}
[Obsolete("TODO: try assosiate Setter.Value property with SetterValueTypeConverter, so far coouldn't make it :(")]
internal static object ConvertSetterValue(XamlSchemaContext context, Setter setter, object value)
{
Type targetType = setter?.Property?.PropertyType;
if (targetType == null)
{
return value;
}
var ttConv = context.GetXamlType(targetType)?.TypeConverter?.ConverterInstance;
if (ttConv != null)
{
value = ttConv.ConvertFromString(value as string);
}
return value;
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/SizeTypeConverter.cs

@ -3,30 +3,21 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class SizeTypeConverter : ITypeConverter
using System.ComponentModel;
public class SizeTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Size.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

19
src/Markup/Avalonia.Markup.Xaml/Converters/ThicknessTypeConverter.cs

@ -3,30 +3,21 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class ThicknessTypeConverter : ITypeConverter
using System.ComponentModel;
public class ThicknessTypeConverter : TypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Thickness.Parse((string)value, culture);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

24
src/Markup/Avalonia.Markup.Xaml/Converters/TimeSpanTypeConverter.cs

@ -3,24 +3,19 @@
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Avalonia.Media;
namespace Avalonia.Markup.Xaml.Converters
{
public class TimeSpanTypeConverter : ITypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string);
}
using System.ComponentModel;
public bool CanConvertTo(IValueContext context, Type destinationType)
public class TimeSpanTypeConverter : System.ComponentModel.TimeSpanConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return false;
return base.CanConvertFrom(context, sourceType);
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var valueStr = (string)value;
if (!valueStr.Contains(":"))
@ -30,12 +25,7 @@ namespace Avalonia.Markup.Xaml.Converters
return TimeSpan.FromSeconds(secs);
}
return TimeSpan.Parse(valueStr);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
return base.ConvertFrom(context, culture, value);
}
}
}

32
src/Markup/Avalonia.Markup.Xaml/Converters/UriTypeConverter.cs

@ -1,32 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Globalization;
using OmniXaml.TypeConversion;
namespace Avalonia.Markup.Xaml.Converters
{
public class UriTypeConverter : ITypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
{
return new Uri((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

27
src/Markup/Avalonia.Markup.Xaml/Data/SourceBindingEndpoint.cs

@ -1,27 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.ComponentModel;
namespace Avalonia.Markup.Xaml.Data
{
public class SourceBindingEndpoint
{
public Type PropertyType { get; }
public INotifyPropertyChanged Source { get; }
public dynamic PropertyGetter { get; }
public Delegate PropertySetter { get; }
public SourceBindingEndpoint(INotifyPropertyChanged source, Type propertyType, dynamic propertyGetter, Delegate propertySetter)
{
Source = source;
PropertyType = propertyType;
PropertyGetter = propertyGetter;
PropertySetter = propertySetter;
}
}
}

4
src/Markup/Avalonia.Markup.Xaml/Data/StyleResourceBinding.cs

@ -40,10 +40,6 @@ namespace Avalonia.Markup.Xaml.Data
object anchor = null,
bool enableDataValidation = false)
{
if (Name == "Red")
{
}
var host = (target as IControl) ?? (anchor as IControl);
var style = anchor as IStyle;
var resource = AvaloniaProperty.UnsetValue;

18
src/Markup/Avalonia.Markup.Xaml/Data/TargetBindingEndpoint.cs

@ -1,18 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Avalonia.Markup.Xaml.Data
{
public class TargetBindingEndpoint
{
public AvaloniaObject Object { get; }
public AvaloniaProperty Property { get; }
public TargetBindingEndpoint(AvaloniaObject obj, AvaloniaProperty property)
{
Object = obj;
Property = property;
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs

@ -1,12 +1,16 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using OmniXaml;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
using Portable.Xaml.Markup;
using PortableXaml;
[MarkupExtensionReturnType(typeof(IBinding))]
public class BindingExtension : MarkupExtension
{
public BindingExtension()
@ -18,9 +22,9 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Path = path;
}
public override object ProvideValue(MarkupExtensionContext extensionContext)
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new Binding
var b = new Binding
{
Converter = Converter,
ConverterParameter = ConverterParameter,
@ -29,16 +33,29 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Mode = Mode,
Path = Path,
Priority = Priority,
RelativeSource = RelativeSource
};
return XamlBinding.FromMarkupExtensionContext(b, serviceProvider);
}
public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
public string ElementName { get; set; }
public object FallbackValue { get; set; } = AvaloniaProperty.UnsetValue;
public BindingMode Mode { get; set; }
[ConstructorArgument("path")]
public string Path { get; set; }
public BindingPriority Priority { get; set; } = BindingPriority.LocalValue;
public object Source { get; set; }
public RelativeSource RelativeSource { get; set; }
}
}

7
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs

@ -1,11 +1,13 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using OmniXaml;
using Avalonia.Markup.Xaml.Data;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
using Portable.Xaml.Markup;
using System;
public class RelativeSourceExtension : MarkupExtension
{
public RelativeSourceExtension()
@ -17,7 +19,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Mode = mode;
}
public override object ProvideValue(MarkupExtensionContext extensionContext)
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new RelativeSource
{
@ -25,6 +27,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
};
}
[ConstructorArgument("mode")]
public RelativeSourceMode Mode { get; set; }
}
}

86
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/Standard/StaticExtension.cs

@ -1,86 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reflection;
using OmniXaml;
using Glass.Core;
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard
{
public class StaticExtension : MarkupExtension
{
public StaticExtension()
{
}
public StaticExtension(string identifier)
{
Identifier = identifier;
}
public string Identifier { get; set; }
public override object ProvideValue(MarkupExtensionContext markupExtensionContext)
{
var typeRepository = markupExtensionContext.ValueContext.TypeRepository;
var typeAndMember = GetTypeAndMember(Identifier);
var prefixAndType = GetPrefixAndType(typeAndMember.Item1);
var xamlType = typeRepository.GetByPrefix(prefixAndType.Item1, prefixAndType.Item2);
return GetValue(xamlType.UnderlyingType, typeAndMember.Item2);
}
private static Tuple<string, string> GetTypeAndMember(string s)
{
var parts = s.Split('.');
if (parts.Length != 2)
{
throw new ArgumentException("Static member must be in the form Type.Member.");
}
return Tuple.Create(parts[0], parts[1]);
}
private static Tuple<string, string> GetPrefixAndType(string s)
{
if (s.Contains(":"))
{
return s.Dicotomize(':');
}
else
{
return new Tuple<string, string>(string.Empty, s);
}
}
private object GetValue(Type type, string name)
{
var t = type;
while (t != null)
{
var result = t.GetTypeInfo().DeclaredMembers.FirstOrDefault(x => x.Name == name);
if (result is PropertyInfo)
{
var property = ((PropertyInfo)result);
if (property.GetMethod.IsStatic)
{
return ((PropertyInfo)result).GetValue(null);
}
}
else if (result is FieldInfo)
{
return ((FieldInfo)result).GetValue(null);
}
t = t.GetTypeInfo().BaseType;
}
throw new ArgumentException($"Static member '{type}.{name}' not found.");
}
}
}

49
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/Standard/TypeExtension.cs

@ -1,49 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
using OmniXaml.Attributes;
using OmniXaml.Typing;
using Glass.Core;
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard
{
[ContentProperty("TargetType")]
public class TypeExtension : MarkupExtension
{
public Type Type { get; set; }
public TypeExtension()
{
}
public TypeExtension(Type type)
{
Type = type;
}
public string TypeName { get; set; }
private Type ResolveFromString(string type, ITypeRepository typeRepository)
{
Guard.ThrowIfNull(type, nameof(type));
var split = type.Split(':');
var prefix = split.Length == 1 ? split[0] : null;
var typeName = split.Length == 1 ? split[1] : split[0];
var xamlType = typeRepository.GetByPrefix(prefix, typeName);
return xamlType.UnderlyingType;
}
public override object ProvideValue(MarkupExtensionContext markupExtensionContext)
{
if (Type != null)
{
return Type;
}
return ResolveFromString(TypeName, markupExtensionContext.ValueContext.TypeRepository);
}
}
}

73
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticExtension.cs

@ -2,85 +2,24 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reflection;
using OmniXaml;
using Glass.Core;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
public class StaticExtension : MarkupExtension
public class StaticExtension : Portable.Xaml.Markup.StaticExtension
{
public StaticExtension()
{
}
public StaticExtension(string identifier)
public StaticExtension(string member)
: base(member)
{
Identifier = identifier;
}
public string Identifier { get; set; }
public override object ProvideValue(MarkupExtensionContext markupExtensionContext)
{
var typeRepository = markupExtensionContext.ValueContext.TypeRepository;
var typeAndMember = GetTypeAndMember(Identifier);
var prefixAndType = GetPrefixAndType(typeAndMember.Item1);
var xamlType = typeRepository.GetByPrefix(prefixAndType.Item1, prefixAndType.Item2);
return GetValue(xamlType.UnderlyingType, typeAndMember.Item2);
}
private static Tuple<string, string> GetTypeAndMember(string s)
{
var parts = s.Split('.');
if (parts.Length != 2)
{
throw new ArgumentException("Static member must be in the form Type.Member.");
}
return Tuple.Create(parts[0], parts[1]);
}
private static Tuple<string, string> GetPrefixAndType(string s)
{
if (s.Contains(":"))
{
return s.Dicotomize(':');
}
else
{
return new Tuple<string, string>(string.Empty, s);
}
}
private object GetValue(Type type, string name)
public override object ProvideValue(IServiceProvider serviceProvider)
{
var t = type;
while (t != null)
{
var result = t.GetTypeInfo().DeclaredMembers.FirstOrDefault(x => x.Name == name);
if (result is PropertyInfo)
{
var property = ((PropertyInfo)result);
if (property.GetMethod.IsStatic)
{
return ((PropertyInfo)result).GetValue(null);
}
}
else if (result is FieldInfo)
{
return ((FieldInfo)result).GetValue(null);
}
t = t.GetTypeInfo().BaseType;
}
throw new ArgumentException($"Static member '{type}.{name}' not found.");
return base.ProvideValue(serviceProvider);
}
}
}

30
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs

@ -0,0 +1,30 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling;
using Portable.Xaml;
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
using Portable.Xaml.Markup;
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
[MarkupExtensionReturnType(typeof(IStyle))]
public class StyleIncludeExtension : MarkupExtension
{
public StyleIncludeExtension()
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var tdc = (ITypeDescriptorContext)serviceProvider;
return new StyleInclude(tdc.GetBaseUri()) { Source = Source };
}
public Uri Source { get; set; }
}
}

18
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs

@ -1,15 +1,16 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reactive.Linq;
using OmniXaml;
using Avalonia.LogicalTree;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Styling;
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
using Portable.Xaml.Markup;
using PortableXaml;
[MarkupExtensionReturnType(typeof(IBinding))]
public class StyleResourceExtension : MarkupExtension
{
public StyleResourceExtension(string name)
@ -17,11 +18,14 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Name = name;
}
public override object ProvideValue(MarkupExtensionContext extensionContext)
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new StyleResourceBinding(this.Name);
return XamlBinding.FromMarkupExtensionContext(
new StyleResourceBinding(Name),
serviceProvider);
}
[ConstructorArgument("name")]
public string Name { get; set; }
}
}

13
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TemplateBindingExtension.cs

@ -1,12 +1,15 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using OmniXaml;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
using System;
using Portable.Xaml.Markup;
[MarkupExtensionReturnType(typeof(Binding))]
public class TemplateBindingExtension : MarkupExtension
{
public TemplateBindingExtension()
@ -18,7 +21,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Path = path;
}
public override object ProvideValue(MarkupExtensionContext extensionContext)
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new Binding
{
@ -32,10 +35,16 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
}
public IValueConverter Converter { get; set; }
public string ElementName { get; set; }
public object FallbackValue { get; set; }
public BindingMode Mode { get; set; }
[ConstructorArgument("path")]
public string Path { get; set; }
public BindingPriority Priority { get; set; } = BindingPriority.TemplatedParent;
}
}

34
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TypeExtension.cs

@ -2,48 +2,22 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
using OmniXaml.Attributes;
using OmniXaml.Typing;
using Glass.Core;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
[ContentProperty("TargetType")]
public class TypeExtension : MarkupExtension
public class TypeExtension : Portable.Xaml.Markup.TypeExtension
{
public Type Type { get; set; }
public TypeExtension()
{
}
public TypeExtension(Type type)
public TypeExtension(string typeName) : base(typeName)
{
Type = type;
}
public string TypeName { get; set; }
private Type ResolveFromString(string type, ITypeRepository typeRepository)
public override object ProvideValue(IServiceProvider serviceProvider)
{
Guard.ThrowIfNull(type, nameof(type));
var split = type.Split(':');
var prefix = split.Length == 1 ? split[0] : null;
var typeName = split.Length == 1 ? split[1] : split[0];
var xamlType = typeRepository.GetByPrefix(prefix, typeName);
return xamlType.UnderlyingType;
}
public override object ProvideValue(MarkupExtensionContext markupExtensionContext)
{
if (Type != null)
{
return Type;
}
return ResolveFromString(TypeName, markupExtensionContext.ValueContext.TypeRepository);
return base.ProvideValue(serviceProvider);
}
}
}

1
src/Markup/Avalonia.Markup.Xaml/OmniXAML

@ -1 +0,0 @@
Subproject commit 544af79d218127b4174da4be19896c5ca78eaa5d

39
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AttributeExtensions.cs

@ -0,0 +1,39 @@
using Avalonia.Markup.Xaml.Templates;
using avm = Avalonia.Metadata;
using pm = Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.PortableXaml
{
internal static class AttributeExtensions
{
public static pm.XamlDeferLoadAttribute ToPortableXaml(this avm.TemplateContentAttribute attrib)
{
if (attrib == null)
{
return null;
}
return new pm.XamlDeferLoadAttribute(typeof(TemplateLoader), typeof(TemplateContent));
}
public static pm.AmbientAttribute ToPortableXaml(this avm.AmbientAttribute attrib)
{
if (attrib == null)
{
return null;
}
return new pm.AmbientAttribute();
}
public static pm.DependsOnAttribute ToPortableXaml(this avm.DependsOnAttribute attrib)
{
if (attrib == null)
{
return null;
}
return new pm.DependsOnAttribute(attrib.Name);
}
}
}

86
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaDefaultTypeConverters.cs

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Avalonia.Markup.Xaml.Converters;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Styling;
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Collections;
using Avalonia.Controls.Templates;
namespace Avalonia.Markup.Xaml.PortableXaml
{
public class AvaloniaDefaultTypeConverters
{
private static Dictionary<Type, Type> _defaultConverters = new Dictionary<Type, Type>()
{
//avalonia default converters
{ typeof(IBitmap), typeof(BitmapTypeConverter)},
{ typeof(IBrush), typeof(BrushTypeConverter) },
{ typeof(Color), typeof(ColorTypeConverter) },
{ typeof(Classes), typeof(ClassesTypeConverter) },
{ typeof(ColumnDefinitions), typeof(ColumnDefinitionsTypeConverter) },
//{ typeof(DateTime), typeof(DateTimeTypeConverter) },
{ typeof(Geometry), typeof(GeometryTypeConverter) },
{ typeof(GridLength), typeof(GridLengthTypeConverter) },
{ typeof(KeyGesture), typeof(KeyGestureConverter) },
{ typeof(AvaloniaList<double>), typeof(AvaloniaListTypeConverter<double>) },
{ typeof(IMemberSelector), typeof(MemberSelectorTypeConverter) },
{ typeof(Point), typeof(PointTypeConverter) },
{ typeof(IList<Point>), typeof(PointsListTypeConverter) },
{ typeof(AvaloniaProperty), typeof(AvaloniaPropertyTypeConverter) },
{ typeof(RelativePoint), typeof(RelativePointTypeConverter) },
{ typeof(RelativeRect), typeof(RelativeRectTypeConverter) },
{ typeof(RowDefinitions), typeof(RowDefinitionsTypeConverter) },
{ typeof(Size), typeof(SizeTypeConverter) },
{ typeof(Selector), typeof(SelectorTypeConverter)},
{ typeof(SolidColorBrush), typeof(BrushTypeConverter) },
{ typeof(Thickness), typeof(ThicknessTypeConverter) },
{ typeof(TimeSpan), typeof(TimeSpanTypeConverter) },
//{ typeof(Uri), typeof(Converters.UriTypeConverter) },
{ typeof(Cursor), typeof(CursorTypeConverter) },
{ typeof(WindowIcon), typeof(IconTypeConverter) },
//{ typeof(FontWeight), typeof(FontWeightConverter) },
};
public static Type GetTypeConverter(Type type)
{
Type converterType;
if (_defaultConverters.TryGetValue(type, out converterType))
{
return converterType;
}
//TODO: probably a smarter way to handle types
//is it needed ??
//Type curType = type;
//while (curType != null)
//{
// if (_defaultConverters.TryGetValue(curType, out converterType))
// {
// if (curType != type)
// {
// _defaultConverters[curType] = converterType;
// }
// return converterType;
// }
// else
// {
// _defaultConverters[curType] = null;
// }
// curType = curType.GetTypeInfo().BaseType;
//}
return null;
}
}
}

71
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaMemberAttributeProvider.cs

@ -0,0 +1,71 @@
using Avalonia.Markup.Xaml.Converters;
using Avalonia.Styling;
using Portable.Xaml.ComponentModel;
using System.ComponentModel;
using System;
using System.Linq;
using System.Reflection;
using avm = Avalonia.Metadata;
using pm = Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.PortableXaml
{
public class AvaloniaMemberAttributeProvider : ICustomAttributeProvider
{
public AvaloniaMemberAttributeProvider(MemberInfo info)
{
_info = info;
}
public object[] GetCustomAttributes(bool inherit)
{
throw new NotImplementedException();
}
public object[] GetCustomAttributes(Type attributeType, bool inherit)
{
Attribute result = null;
if (attributeType == typeof(pm.XamlDeferLoadAttribute))
{
result = _info.GetCustomAttribute<avm.TemplateContentAttribute>(inherit)
.ToPortableXaml();
}
else if (attributeType == typeof(pm.AmbientAttribute))
{
result = _info.GetCustomAttribute<avm.AmbientAttribute>(inherit)
.ToPortableXaml();
}
else if (attributeType == typeof(pm.DependsOnAttribute))
{
result = _info.GetCustomAttribute<avm.DependsOnAttribute>(inherit)
.ToPortableXaml();
}
else if (attributeType == typeof(TypeConverterAttribute) &&
_info.DeclaringType == typeof(Setter) &&
_info.Name == nameof(Setter.Value))
{
//actually it never comes here looks like if property type is object
//Portable.Xaml is not searching for Type Converter
result = new TypeConverterAttribute(typeof(SetterValueTypeConverter));
}
if (result == null)
{
var attr = _info.GetCustomAttributes(attributeType, inherit);
return (attr as object[]) ?? attr.ToArray();
}
else
{
return new object[] { result };
}
}
public bool IsDefined(Type attributeType, bool inherit)
{
throw new NotImplementedException();
}
private readonly MemberInfo _info;
}
}

56
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaNameScope.cs

@ -0,0 +1,56 @@
using System.Collections.Generic;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.PortableXaml
{
internal class AvaloniaNameScope : Portable.Xaml.Markup.INameScope
{
public object Instance { get; set; }
private Dictionary<string, object> _names = new Dictionary<string, object>();
public object FindName(string name)
{
object result;
if (_names.TryGetValue(name, out result))
return result;
return null;
}
public void RegisterName(string name, object scopedElement)
{
if (scopedElement != null)
_names.Add(name, scopedElement);
//TODO: ???
//var control = scopedElement as Control;
//if (control != null)
//{
// var nameScope = (Instance as INameScope) ?? control.FindNameScope();
// if (nameScope != null)
// {
// nameScope.Register(name, scopedElement);
// }
//}
}
public void UnregisterName(string name)
{
}
public void RegisterOnNameScope(object target)
{
var nameScope = target as INameScope;
if (nameScope != null)
{
foreach (var v in _names)
{
nameScope.Register(v.Key, v.Value);
}
}
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save