Merge branch '3.6.0'
This commit is contained in:
Коммит
55937add66
|
@ -2,4 +2,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProguardConfiguration Include="$(MSBuildThisFileDirectory)proguard.cfg" />
|
<ProguardConfiguration Include="$(MSBuildThisFileDirectory)proguard.cfg" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<Target Name="ValidateTargetFrameworkVersionForForms" BeforeTargets="CoreCompile" Condition="'$(XFDisableTargetFrameworkValidation)' != 'True'">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MinTargetFrameworkVersionForForms>8.1</MinTargetFrameworkVersionForForms>
|
||||||
|
<TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</TargetFrameworkVersionWithoutV>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Code="XF005" Condition="$(TargetFrameworkVersionWithoutV) < $(MinTargetFrameworkVersionForForms)"
|
||||||
|
Text="The %24(TargetFrameworkVersion) for $(ProjectName) ($(TargetFrameworkVersion)) is less than the minimum required %24(TargetFrameworkVersion) for Xamarin.Forms ($(MinTargetFrameworkVersionForForms)). You need to increase the %24(TargetFrameworkVersion) for $(ProjectName)." />
|
||||||
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Target Name="ValidateTargetFrameworkVersionForMaterial" BeforeTargets="BeforeCompile">
|
<Target Name="ValidateTargetFrameworkVersionForMaterial" BeforeTargets="CoreCompile" Condition="'$(XFDisableTargetFrameworkValidation)' != 'True'">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MinTargetFrameworkVersionForMaterial>9.0</MinTargetFrameworkVersionForMaterial>
|
<MinTargetFrameworkVersionForMaterial>9.0</MinTargetFrameworkVersionForMaterial>
|
||||||
<TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</TargetFrameworkVersionWithoutV>
|
<TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</TargetFrameworkVersionWithoutV>
|
||||||
|
|
|
@ -321,8 +321,8 @@ namespace Xamarin.Forms.Controls
|
||||||
new GalleryPageFactory(() => new OpenGLViewCoreGalleryPage(), "OpenGLView Gallery"),
|
new GalleryPageFactory(() => new OpenGLViewCoreGalleryPage(), "OpenGLView Gallery"),
|
||||||
new GalleryPageFactory(() => new PickerCoreGalleryPage(), "Picker Gallery"),
|
new GalleryPageFactory(() => new PickerCoreGalleryPage(), "Picker Gallery"),
|
||||||
new GalleryPageFactory(() => new ProgressBarCoreGalleryPage(), "ProgressBar Gallery"),
|
new GalleryPageFactory(() => new ProgressBarCoreGalleryPage(), "ProgressBar Gallery"),
|
||||||
new GalleryPageFactory(() => new MaterialProgressBarGallery(), "[Material] ProgressBar & Slider Gallery"),
|
new GalleryPageFactory(() => new MaterialProgressBarGallery(), "ProgressBar & Slider Gallery (Material)"),
|
||||||
new GalleryPageFactory(() => new MaterialActivityIndicatorGallery(), "[Material] ActivityIndicator Gallery"),
|
new GalleryPageFactory(() => new MaterialActivityIndicatorGallery(), "ActivityIndicator Gallery (Material)"),
|
||||||
new GalleryPageFactory(() => new ScrollGallery(), "ScrollView Gallery"),
|
new GalleryPageFactory(() => new ScrollGallery(), "ScrollView Gallery"),
|
||||||
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
|
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
|
||||||
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Both), "ScrollView Gallery 2D"),
|
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Both), "ScrollView Gallery 2D"),
|
||||||
|
|
|
@ -35,6 +35,10 @@ namespace Xamarin.Forms.Core.Design
|
||||||
new System.ComponentModel.TypeConverterAttribute (typeof (NonExclusiveEnumConverter<NamedSize>))));
|
new System.ComponentModel.TypeConverterAttribute (typeof (NonExclusiveEnumConverter<NamedSize>))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddCallback(typeof(VisualElement), builder => builder.AddCustomAttributes(
|
||||||
|
"Visual",
|
||||||
|
new System.ComponentModel.TypeConverterAttribute(typeof(VisualDesignTypeConverter))));
|
||||||
|
|
||||||
// TODO: OnPlatform/OnIdiom
|
// TODO: OnPlatform/OnIdiom
|
||||||
// These two should be proper markup extensions, to follow WPF syntax for those.
|
// These two should be proper markup extensions, to follow WPF syntax for those.
|
||||||
// That would allow us to turn on XAML validation, which otherwise fails.
|
// That would allow us to turn on XAML validation, which otherwise fails.
|
||||||
|
@ -42,7 +46,7 @@ namespace Xamarin.Forms.Core.Design
|
||||||
// the language service can find the type by its name. That class can be internal
|
// the language service can find the type by its name. That class can be internal
|
||||||
// though, since its visibility in the markup is controlled by the EditorBrowsableAttribute.
|
// though, since its visibility in the markup is controlled by the EditorBrowsableAttribute.
|
||||||
// Make OnPlatform/OnIdiom visible for intellisense, and set as markup extension.
|
// Make OnPlatform/OnIdiom visible for intellisense, and set as markup extension.
|
||||||
AddCallback (typeof (OnPlatform<>), builder => builder.AddCustomAttributes (new Attribute[] {
|
AddCallback(typeof (OnPlatform<>), builder => builder.AddCustomAttributes (new Attribute[] {
|
||||||
new EditorBrowsableAttribute (EditorBrowsableState.Always),
|
new EditorBrowsableAttribute (EditorBrowsableState.Always),
|
||||||
//new System.ComponentModel.TypeConverterAttribute(typeof(AnythingConverter)),
|
//new System.ComponentModel.TypeConverterAttribute(typeof(AnythingConverter)),
|
||||||
//new System.Windows.Markup.MarkupExtensionReturnTypeAttribute (),
|
//new System.Windows.Markup.MarkupExtensionReturnTypeAttribute (),
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
namespace Xamarin.Forms.Core.Design
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public class VisualDesignTypeConverter : TypeConverter
|
||||||
|
{
|
||||||
|
public VisualDesignTypeConverter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StandardValuesCollection Values
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||||
|
{
|
||||||
|
// This tells XAML this converter can be used to process strings
|
||||||
|
// Without this the values won't show up as hints
|
||||||
|
if (sourceType == typeof(string))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return base.CanConvertFrom(context, sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||||
|
{
|
||||||
|
if(Values == null)
|
||||||
|
{
|
||||||
|
var derivedNames = new List<string>();
|
||||||
|
var baseType = typeof(IVisual);
|
||||||
|
|
||||||
|
var typeElements = typeof(View).Assembly.ExportedTypes.Where(t => baseType.IsAssignableFrom(t) && t.Name != baseType.Name);
|
||||||
|
|
||||||
|
foreach (var typeElement in typeElements)
|
||||||
|
{
|
||||||
|
string name = typeElement.Name;
|
||||||
|
if (name.EndsWith("Visual", StringComparison.OrdinalIgnoreCase))
|
||||||
|
name = name.Substring(0, name.Length - 6);
|
||||||
|
|
||||||
|
derivedNames.Add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Values = new StandardValuesCollection(derivedNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,6 +50,7 @@
|
||||||
<Compile Include="..\Xamarin.Forms.Core\Properties\GlobalAssemblyInfo.cs">
|
<Compile Include="..\Xamarin.Forms.Core\Properties\GlobalAssemblyInfo.cs">
|
||||||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="VisualDesignTypeConverter.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition=" '$(OS)' != 'Unix' ">
|
<ItemGroup Condition=" '$(OS)' != 'Unix' ">
|
||||||
<Compile Include="AttributeTableBuilder.cs" />
|
<Compile Include="AttributeTableBuilder.cs" />
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Xamarin.Forms.Core.UnitTests
|
namespace Xamarin.Forms.Core.UnitTests
|
||||||
|
@ -72,6 +74,21 @@ namespace Xamarin.Forms.Core.UnitTests
|
||||||
Assert.IsTrue(IsLayoutWithItemsSource(itemsSource, layout));
|
Assert.IsTrue(IsLayoutWithItemsSource(itemsSource, layout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TracksRemoveAll()
|
||||||
|
{
|
||||||
|
var layout = new StackLayout
|
||||||
|
{
|
||||||
|
IsPlatformEnabled = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var itemsSource = new ObservableRangeCollection<int>(Enumerable.Range(0, 10));
|
||||||
|
BindableLayout.SetItemsSource(layout, itemsSource);
|
||||||
|
|
||||||
|
itemsSource.RemoveAll();
|
||||||
|
Assert.IsTrue(IsLayoutWithItemsSource(itemsSource, layout));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TracksReplace()
|
public void TracksReplace()
|
||||||
{
|
{
|
||||||
|
@ -377,6 +394,27 @@ namespace Xamarin.Forms.Core.UnitTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ObservableRangeCollection<T> : ObservableCollection<T>
|
||||||
|
{
|
||||||
|
public ObservableRangeCollection(IEnumerable<T> collection)
|
||||||
|
: base(collection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAll()
|
||||||
|
{
|
||||||
|
CheckReentrancy();
|
||||||
|
|
||||||
|
var changedItems = new List<T>(Items);
|
||||||
|
foreach (var i in changedItems)
|
||||||
|
Items.Remove(i);
|
||||||
|
|
||||||
|
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
|
||||||
|
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
||||||
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MyDataTemplateSelectorTest : DataTemplateSelector
|
class MyDataTemplateSelectorTest : DataTemplateSelector
|
||||||
{
|
{
|
||||||
readonly Func<object, BindableObject, DataTemplate> _func;
|
readonly Func<object, BindableObject, DataTemplate> _func;
|
||||||
|
|
|
@ -223,9 +223,9 @@ namespace Xamarin.Forms
|
||||||
{
|
{
|
||||||
if (e.OldStartingIndex == -1)
|
if (e.OldStartingIndex == -1)
|
||||||
goto case NotifyCollectionChangedAction.Reset;
|
goto case NotifyCollectionChangedAction.Reset;
|
||||||
for (int i = 0; i < e.OldItems.Count; ++i)
|
for (int i = 0; i < e.OldItems.Count; i++)
|
||||||
{
|
{
|
||||||
layout.Children.RemoveAt(i + e.OldStartingIndex);
|
layout.Children.RemoveAt(e.OldStartingIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Xamarin.Forms
|
||||||
{
|
{
|
||||||
protected HandlerAttribute(Type handler, Type target, Type[] supportedVisuals = null)
|
protected HandlerAttribute(Type handler, Type target, Type[] supportedVisuals = null)
|
||||||
{
|
{
|
||||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualRendererMarker.Default) };
|
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualMarker.DefaultVisual) };
|
||||||
TargetType = target;
|
TargetType = target;
|
||||||
HandlerType = handler;
|
HandlerType = handler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,31 @@ namespace Xamarin.Forms.Internals
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static object[] GetCustomAttributesSafe(this Assembly assembly, Type attrType)
|
||||||
|
{
|
||||||
|
object[] attributes = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if NETSTANDARD2_0
|
||||||
|
attributes = assembly.GetCustomAttributes(attrType, true);
|
||||||
|
#else
|
||||||
|
attributes = assembly.GetCustomAttributes(attrType).ToArray();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (System.IO.FileNotFoundException)
|
||||||
|
{
|
||||||
|
// Sometimes the previewer doesn't actually have everything required for these loads to work
|
||||||
|
Log.Warning(nameof(Registrar), "Could not load assembly: {0} for Attribute {1} | Some renderers may not be loaded", assembly.FullName, attrType.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type[] GetExportedTypes(this Assembly assembly)
|
||||||
|
{
|
||||||
|
return assembly.ExportedTypes.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsAssignableFrom(this Type self, Type c)
|
public static bool IsAssignableFrom(this Type self, Type c)
|
||||||
{
|
{
|
||||||
return self.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
|
return self.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
|
||||||
|
|
|
@ -19,8 +19,8 @@ namespace Xamarin.Forms.Internals
|
||||||
public class Registrar<TRegistrable> where TRegistrable : class
|
public class Registrar<TRegistrable> where TRegistrable : class
|
||||||
{
|
{
|
||||||
readonly Dictionary<Type, Dictionary<Type, Type>> _handlers = new Dictionary<Type, Dictionary<Type, Type>>();
|
readonly Dictionary<Type, Dictionary<Type, Type>> _handlers = new Dictionary<Type, Dictionary<Type, Type>>();
|
||||||
static Type _defaultVisualType = typeof(VisualRendererMarker.Default);
|
static Type _defaultVisualType = typeof(VisualMarker.DefaultVisual);
|
||||||
static Type _materialVisualType = typeof(VisualRendererMarker.Material);
|
static Type _materialVisualType = typeof(VisualMarker.MaterialVisual);
|
||||||
|
|
||||||
static Type[] _defaultVisualRenderers = new[] { _defaultVisualType };
|
static Type[] _defaultVisualRenderers = new[] { _defaultVisualType };
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ namespace Xamarin.Forms
|
||||||
public sealed class RenderWithAttribute : Attribute
|
public sealed class RenderWithAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
public RenderWithAttribute(Type type) : this(type, new[] { typeof(VisualRendererMarker.Default) })
|
public RenderWithAttribute(Type type) : this(type, new[] { typeof(VisualMarker.DefaultVisual) })
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderWithAttribute(Type type, Type[] supportedVisuals)
|
public RenderWithAttribute(Type type, Type[] supportedVisuals)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualRendererMarker.Default) };
|
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualMarker.DefaultVisual) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type[] SupportedVisuals { get; }
|
public Type[] SupportedVisuals { get; }
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Xamarin.Forms
|
|
||||||
{
|
|
||||||
public static class VisualMarker
|
|
||||||
{
|
|
||||||
static bool _isMaterialRegistered = false;
|
|
||||||
static bool _warnedAboutMaterial = false;
|
|
||||||
|
|
||||||
public static IVisual MatchParent { get; } = new VisualRendererMarker.MatchParent();
|
|
||||||
public static IVisual Default { get; } = new VisualRendererMarker.Default();
|
|
||||||
public static IVisual Material { get; } = new VisualRendererMarker.Material();
|
|
||||||
|
|
||||||
internal static void RegisterMaterial() => _isMaterialRegistered = true;
|
|
||||||
internal static void MaterialCheck()
|
|
||||||
{
|
|
||||||
if (_isMaterialRegistered || _warnedAboutMaterial)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_warnedAboutMaterial = true;
|
|
||||||
if (Device.RuntimePlatform == Device.iOS)
|
|
||||||
Internals.Log.Warning("Visual", "Material needs to be registered on iOS by calling FormsMaterial.Init() after the Xamarin.Forms.Forms.Init method call.");
|
|
||||||
else if (Device.RuntimePlatform != Device.Android)
|
|
||||||
Internals.Log.Warning("Visual", $"Material is currently not support on {Device.RuntimePlatform}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VisualRendererMarker
|
|
||||||
{
|
|
||||||
public sealed class Material : IVisual { internal Material() { } }
|
|
||||||
public sealed class Default : IVisual { internal Default() { } }
|
|
||||||
internal sealed class MatchParent : IVisual { internal MatchParent() { } }
|
|
||||||
}
|
|
||||||
|
|
||||||
[TypeConverter(typeof(VisualTypeConverter))]
|
|
||||||
public interface IVisual
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Xaml.TypeConversion(typeof(IVisual))]
|
|
||||||
public class VisualTypeConverter : TypeConverter
|
|
||||||
{
|
|
||||||
public override object ConvertFromInvariantString(string value)
|
|
||||||
{
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
var sc = StringComparison.OrdinalIgnoreCase;
|
|
||||||
if (value.Equals(nameof(VisualMarker.MatchParent), sc))
|
|
||||||
return VisualMarker.MatchParent;
|
|
||||||
else if (value.Equals(nameof(VisualMarker.Material), sc))
|
|
||||||
return VisualMarker.Material;
|
|
||||||
else
|
|
||||||
return VisualMarker.Default;
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(IVisual)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Xamarin.Forms
|
||||||
|
{
|
||||||
|
[TypeConverter(typeof(VisualTypeConverter))]
|
||||||
|
public interface IVisual
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Xamarin.Forms
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||||
|
public class VisualAttribute : Attribute
|
||||||
|
{
|
||||||
|
public VisualAttribute(string key, Type visual)
|
||||||
|
{
|
||||||
|
this.Key = key;
|
||||||
|
this.Visual = visual;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string Key { get; }
|
||||||
|
internal Type Visual { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
namespace Xamarin.Forms
|
||||||
|
{
|
||||||
|
public static class VisualMarker
|
||||||
|
{
|
||||||
|
static bool _isMaterialRegistered = false;
|
||||||
|
static bool _warnedAboutMaterial = false;
|
||||||
|
|
||||||
|
public static IVisual MatchParent { get; } = new MatchParentVisual();
|
||||||
|
public static IVisual Default { get; } = new DefaultVisual();
|
||||||
|
public static IVisual Material { get; } = new MaterialVisual();
|
||||||
|
|
||||||
|
internal static void RegisterMaterial() => _isMaterialRegistered = true;
|
||||||
|
internal static void MaterialCheck()
|
||||||
|
{
|
||||||
|
if (_isMaterialRegistered || _warnedAboutMaterial)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_warnedAboutMaterial = true;
|
||||||
|
if (Device.RuntimePlatform == Device.iOS)
|
||||||
|
Internals.Log.Warning("Visual", "Material needs to be registered on iOS by calling FormsMaterial.Init() after the Xamarin.Forms.Forms.Init method call.");
|
||||||
|
else if (Device.RuntimePlatform != Device.Android)
|
||||||
|
Internals.Log.Warning("Visual", $"Material is currently not support on {Device.RuntimePlatform}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class MaterialVisual : IVisual { public MaterialVisual() { } }
|
||||||
|
public sealed class DefaultVisual : IVisual { public DefaultVisual() { } }
|
||||||
|
internal sealed class MatchParentVisual : IVisual { public MatchParentVisual() { } }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Xamarin.Forms.Internals;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Forms
|
||||||
|
{
|
||||||
|
[Xaml.TypeConversion(typeof(IVisual))]
|
||||||
|
public class VisualTypeConverter : TypeConverter
|
||||||
|
{
|
||||||
|
static Dictionary<string, IVisual> _visualTypeMappings;
|
||||||
|
void InitMappings()
|
||||||
|
{
|
||||||
|
var mappings = new Dictionary<string, IVisual>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
Assembly[] assemblies = Device.GetAssemblies();
|
||||||
|
|
||||||
|
// Check for IVisual Types
|
||||||
|
foreach (var assembly in assemblies)
|
||||||
|
Register(assembly, mappings);
|
||||||
|
|
||||||
|
if (Internals.Registrar.ExtraAssemblies != null)
|
||||||
|
foreach (var assembly in Internals.Registrar.ExtraAssemblies)
|
||||||
|
Register(assembly, mappings);
|
||||||
|
|
||||||
|
|
||||||
|
// Check for visual assembly attributes after scanning for IVisual Types
|
||||||
|
// this will let users replace the default visual names if they want to
|
||||||
|
foreach (var assembly in assemblies)
|
||||||
|
RegisterFromAttributes(assembly, mappings);
|
||||||
|
|
||||||
|
if (Internals.Registrar.ExtraAssemblies != null)
|
||||||
|
foreach (var assembly in Internals.Registrar.ExtraAssemblies)
|
||||||
|
RegisterFromAttributes(assembly, mappings);
|
||||||
|
|
||||||
|
_visualTypeMappings = mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RegisterFromAttributes(Assembly assembly, Dictionary<string, IVisual> mappings)
|
||||||
|
{
|
||||||
|
object[] attributes = assembly.GetCustomAttributesSafe(typeof(VisualAttribute));
|
||||||
|
|
||||||
|
if (attributes != null)
|
||||||
|
{
|
||||||
|
foreach (VisualAttribute attribute in attributes)
|
||||||
|
{
|
||||||
|
var visual = CreateVisual(attribute.Visual);
|
||||||
|
if (visual != null)
|
||||||
|
mappings[attribute.Key] = visual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(Assembly assembly, Dictionary<string, IVisual> mappings)
|
||||||
|
{
|
||||||
|
if (assembly.IsDynamic)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetExportedTypes())
|
||||||
|
if (typeof(IVisual).IsAssignableFrom(type) && type != typeof(IVisual))
|
||||||
|
Register(type, mappings);
|
||||||
|
}
|
||||||
|
catch(NotSupportedException)
|
||||||
|
{
|
||||||
|
Log.Warning("Visual", $"Cannot scan assembly {assembly.FullName} for Visual types.");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Log.Warning("Visual", $"Unable to load a dependent assembly for {assembly.FullName}. It cannot be scanned for Visual types.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(Type visual, Dictionary<string, IVisual> mappings)
|
||||||
|
{
|
||||||
|
IVisual registeredVisual = CreateVisual(visual);
|
||||||
|
if (registeredVisual == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string name = visual.Name;
|
||||||
|
string fullName = visual.FullName;
|
||||||
|
|
||||||
|
if (name.EndsWith("Visual", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
name = name.Substring(0, name.Length - 6);
|
||||||
|
fullName = fullName.Substring(0, fullName.Length - 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
mappings[name] = registeredVisual;
|
||||||
|
mappings[fullName] = registeredVisual;
|
||||||
|
mappings[$"{name}Visual"] = registeredVisual;
|
||||||
|
mappings[$"{fullName}Visual"] = registeredVisual;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static IVisual CreateVisual(Type visualType)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (IVisual)Activator.CreateInstance(visualType);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Internals.Log.Warning("Visual", $"Unable to register {visualType} please add a public default constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertFromInvariantString(string value)
|
||||||
|
{
|
||||||
|
if (_visualTypeMappings == null)
|
||||||
|
InitMappings();
|
||||||
|
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
IVisual returnValue = null;
|
||||||
|
if (_visualTypeMappings.TryGetValue(value, out returnValue))
|
||||||
|
return returnValue;
|
||||||
|
|
||||||
|
return VisualMarker.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(IVisual)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,8 +114,14 @@ namespace Xamarin.Forms.Xaml
|
||||||
var xfExtendedTypeConverter = xfTypeConverter as IExtendedTypeConverter;
|
var xfExtendedTypeConverter = xfTypeConverter as IExtendedTypeConverter;
|
||||||
if (xfExtendedTypeConverter != null)
|
if (xfExtendedTypeConverter != null)
|
||||||
return value = xfExtendedTypeConverter.ConvertFromInvariantString(str, serviceProvider);
|
return value = xfExtendedTypeConverter.ConvertFromInvariantString(str, serviceProvider);
|
||||||
if (xfTypeConverter != null)
|
if (xfTypeConverter != null) {
|
||||||
return value = xfTypeConverter.ConvertFromInvariantString(str);
|
try {
|
||||||
|
return value = xfTypeConverter.ConvertFromInvariantString(str);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new XamlParseException("Type conversion failed", serviceProvider, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
var converterType = converter?.GetType();
|
var converterType = converter?.GetType();
|
||||||
if (converterType != null)
|
if (converterType != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,8 @@ using System.ComponentModel;
|
||||||
using CoreGraphics;
|
using CoreGraphics;
|
||||||
using MaterialComponents;
|
using MaterialComponents;
|
||||||
using UIKit;
|
using UIKit;
|
||||||
using Xamarin.Forms;
|
|
||||||
using MButton = MaterialComponents.Button;
|
using MButton = MaterialComponents.Button;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialStepperRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.iOS.Material
|
namespace Xamarin.Forms.Platform.iOS.Material
|
||||||
{
|
{
|
||||||
public class MaterialStepperRenderer : ViewRenderer<Stepper, MaterialStepper>
|
public class MaterialStepperRenderer : ViewRenderer<Stepper, MaterialStepper>
|
||||||
|
|
|
@ -15,12 +15,13 @@ using Xamarin.Forms;
|
||||||
[assembly: AssemblyVersion("2.0.0.0")]
|
[assembly: AssemblyVersion("2.0.0.0")]
|
||||||
[assembly: AssemblyFileVersion("2.0.0.0")]
|
[assembly: AssemblyFileVersion("2.0.0.0")]
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.ActivityIndicator), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialActivityIndicatorRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.ActivityIndicator), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialActivityIndicatorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialButtonRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialButtonRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialEntryRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialEntryRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialFrameRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialFrameRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialProgressBarRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialProgressBarRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialSliderRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialSliderRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialTimePickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialTimePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialPickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialDatePickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialDatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialStepperRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
|
@ -11,7 +11,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
||||||
using AProgressBar = Android.Widget.ProgressBar;
|
using AProgressBar = Android.Widget.ProgressBar;
|
||||||
using AView = Android.Views.View;
|
using AView = Android.Views.View;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(ActivityIndicator), typeof(MaterialActivityIndicatorRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(ActivityIndicator), typeof(MaterialActivityIndicatorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ using AColor = Android.Graphics.Color;
|
||||||
using AView = Android.Views.View;
|
using AView = Android.Views.View;
|
||||||
using MButton = Android.Support.Design.Button.MaterialButton;
|
using MButton = Android.Support.Design.Button.MaterialButton;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(MaterialButtonRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(MaterialButtonRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Platform.Android.Material;
|
using Xamarin.Forms.Platform.Android.Material;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(MaterialDatePickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(MaterialDatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ using Android.Widget;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Platform.Android.Material;
|
using Xamarin.Forms.Platform.Android.Material;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(MaterialEntryRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(MaterialEntryRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
public sealed class MaterialEntryRenderer : EntryRendererBase<MaterialFormsTextInputLayout>
|
public sealed class MaterialEntryRenderer : EntryRendererBase<MaterialFormsTextInputLayout>
|
||||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
||||||
using AView = Android.Views.View;
|
using AView = Android.Views.View;
|
||||||
using MaterialCardView = Android.Support.Design.Card.MaterialCardView;
|
using MaterialCardView = Android.Support.Design.Card.MaterialCardView;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(MaterialFrameRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(MaterialFrameRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Platform.Android.Material;
|
using Xamarin.Forms.Platform.Android.Material;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(MaterialPickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(MaterialPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
||||||
using AProgressBar = Android.Widget.ProgressBar;
|
using AProgressBar = Android.Widget.ProgressBar;
|
||||||
using AView = Android.Views.View;
|
using AView = Android.Views.View;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(ProgressBar), typeof(MaterialProgressBarRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(ProgressBar), typeof(MaterialProgressBarRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.FastRenderers;
|
||||||
using Xamarin.Forms.Platform.Android.Material;
|
using Xamarin.Forms.Platform.Android.Material;
|
||||||
using AView = Android.Views.View;
|
using AView = Android.Views.View;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(MaterialSliderRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(MaterialSliderRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
||||||
using AButton = Android.Widget.Button;
|
using AButton = Android.Widget.Button;
|
||||||
using MButton = Android.Support.Design.Button.MaterialButton;
|
using MButton = Android.Support.Design.Button.MaterialButton;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(MaterialStepperRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(MaterialStepperRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Platform.Android.Material;
|
using Xamarin.Forms.Platform.Android.Material;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(MaterialTimePickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(MaterialTimePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
|
||||||
|
|
||||||
namespace Xamarin.Forms.Platform.Android.Material
|
namespace Xamarin.Forms.Platform.Android.Material
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,11 @@ namespace Xamarin.Forms
|
||||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||||
public sealed class ExportRendererAttribute : HandlerAttribute
|
public sealed class ExportRendererAttribute : HandlerAttribute
|
||||||
{
|
{
|
||||||
public ExportRendererAttribute(Type handler, Type target) : base(handler, target)
|
public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,11 @@ namespace Xamarin.Forms.Platform.Tizen
|
||||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||||
public sealed class ExportRendererAttribute : HandlerAttribute
|
public sealed class ExportRendererAttribute : HandlerAttribute
|
||||||
{
|
{
|
||||||
public ExportRendererAttribute(Type handler, Type target) : base(handler, target)
|
public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,11 @@ namespace Xamarin.Forms.Platform.UWP
|
||||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||||
public sealed class ExportRendererAttribute : HandlerAttribute
|
public sealed class ExportRendererAttribute : HandlerAttribute
|
||||||
{
|
{
|
||||||
public ExportRendererAttribute(Type handler, Type target) : base(handler, target)
|
public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,11 @@ namespace Xamarin.Forms.Platform.WPF
|
||||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||||
public sealed class ExportRendererAttribute : HandlerAttribute
|
public sealed class ExportRendererAttribute : HandlerAttribute
|
||||||
{
|
{
|
||||||
public ExportRendererAttribute(Type handler, Type target) : base(handler, target)
|
public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,12 @@ namespace Xamarin.Forms.Sandbox
|
||||||
// This code is called from the App Constructor so just initialize the main page of the application here
|
// This code is called from the App Constructor so just initialize the main page of the application here
|
||||||
void InitializeMainPage()
|
void InitializeMainPage()
|
||||||
{
|
{
|
||||||
MainPage = new ContentPage()
|
/*MainPage = new ContentPage()
|
||||||
{
|
{
|
||||||
Content = CreateStackLayout(new[] { new Button() { Text = "text" } })
|
Content = CreateStackLayout(new[] { new Button() { Text = "text" } })
|
||||||
};
|
};
|
||||||
|
MainPage.Visual = VisualMarker.Material;*/
|
||||||
|
MainPage = new MainPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Xamarin.Forms.Sandbox.MainPage">
|
||||||
|
<ContentPage.Content>
|
||||||
|
<StackLayout>
|
||||||
|
<Button Text="Material text" Visual="MaTeRiAl" />
|
||||||
|
</StackLayout>
|
||||||
|
</ContentPage.Content>
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Forms.Sandbox
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class MainPage : ContentPage
|
||||||
|
{
|
||||||
|
public MainPage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ContentPage
|
||||||
|
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Xamarin.Forms.Xaml.UnitTests.Gh5378_1">
|
||||||
|
<Label Margin="1,2,3," />
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Core.UnitTests;
|
||||||
|
|
||||||
|
namespace Xamarin.Forms.Xaml.UnitTests
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Skip)]
|
||||||
|
public partial class Gh5378_1 : ContentPage
|
||||||
|
{
|
||||||
|
public Gh5378_1() => InitializeComponent();
|
||||||
|
public Gh5378_1(bool useCompiledXaml)
|
||||||
|
{
|
||||||
|
//this stub will be replaced at compile time
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixture] class Tests
|
||||||
|
{
|
||||||
|
[SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
|
||||||
|
[TearDown] public void TearDown() => Device.PlatformServices = null;
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReportSyntaxError([Values(false, true)]bool useCompiledXaml)
|
||||||
|
{
|
||||||
|
if (useCompiledXaml)
|
||||||
|
Assert.Throws<XamlParseException>(() => MockCompiler.Compile(typeof(Gh5378_1)));
|
||||||
|
else
|
||||||
|
Assert.Throws<XamlParseException>(() => new Gh5378_1(useCompiledXaml));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Xaml.UnitTests.Gh5378_2">
|
||||||
|
<Button Clicked="{Binding FooBar}" />
|
||||||
|
</ContentPage>
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Core.UnitTests;
|
||||||
|
|
||||||
|
namespace Xamarin.Forms.Xaml.UnitTests
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Skip)]
|
||||||
|
public partial class Gh5378_2 : ContentPage
|
||||||
|
{
|
||||||
|
public Gh5378_2()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gh5378_2(bool useCompiledXaml)
|
||||||
|
{
|
||||||
|
//this stub will be replaced at compile time
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixture] class Tests
|
||||||
|
{
|
||||||
|
[SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
|
||||||
|
[TearDown] public void TearDown() => Device.PlatformServices = null;
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReportSyntaxError([Values(false, true)]bool useCompiledXaml)
|
||||||
|
{
|
||||||
|
if (useCompiledXaml)
|
||||||
|
Assert.Throws<XamlParseException>(() => MockCompiler.Compile(typeof(Gh5378_2)));
|
||||||
|
else
|
||||||
|
Assert.Throws<XamlParseException>(() => new Gh5378_2(useCompiledXaml));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче