Merge branch '3.6.0'
This commit is contained in:
Коммит
55937add66
|
@ -2,4 +2,12 @@
|
|||
<ItemGroup>
|
||||
<ProguardConfiguration Include="$(MSBuildThisFileDirectory)proguard.cfg" />
|
||||
</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>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="ValidateTargetFrameworkVersionForMaterial" BeforeTargets="BeforeCompile">
|
||||
<Target Name="ValidateTargetFrameworkVersionForMaterial" BeforeTargets="CoreCompile" Condition="'$(XFDisableTargetFrameworkValidation)' != 'True'">
|
||||
<PropertyGroup>
|
||||
<MinTargetFrameworkVersionForMaterial>9.0</MinTargetFrameworkVersionForMaterial>
|
||||
<TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</TargetFrameworkVersionWithoutV>
|
||||
|
|
|
@ -321,8 +321,8 @@ namespace Xamarin.Forms.Controls
|
|||
new GalleryPageFactory(() => new OpenGLViewCoreGalleryPage(), "OpenGLView Gallery"),
|
||||
new GalleryPageFactory(() => new PickerCoreGalleryPage(), "Picker Gallery"),
|
||||
new GalleryPageFactory(() => new ProgressBarCoreGalleryPage(), "ProgressBar Gallery"),
|
||||
new GalleryPageFactory(() => new MaterialProgressBarGallery(), "[Material] ProgressBar & Slider Gallery"),
|
||||
new GalleryPageFactory(() => new MaterialActivityIndicatorGallery(), "[Material] ActivityIndicator Gallery"),
|
||||
new GalleryPageFactory(() => new MaterialProgressBarGallery(), "ProgressBar & Slider Gallery (Material)"),
|
||||
new GalleryPageFactory(() => new MaterialActivityIndicatorGallery(), "ActivityIndicator Gallery (Material)"),
|
||||
new GalleryPageFactory(() => new ScrollGallery(), "ScrollView Gallery"),
|
||||
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
|
||||
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>))));
|
||||
}
|
||||
|
||||
AddCallback(typeof(VisualElement), builder => builder.AddCustomAttributes(
|
||||
"Visual",
|
||||
new System.ComponentModel.TypeConverterAttribute(typeof(VisualDesignTypeConverter))));
|
||||
|
||||
// TODO: OnPlatform/OnIdiom
|
||||
// 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.
|
||||
|
@ -42,7 +46,7 @@ namespace Xamarin.Forms.Core.Design
|
|||
// 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.
|
||||
// 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 System.ComponentModel.TypeConverterAttribute(typeof(AnythingConverter)),
|
||||
//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">
|
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="VisualDesignTypeConverter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(OS)' != 'Unix' ">
|
||||
<Compile Include="AttributeTableBuilder.cs" />
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Forms.Core.UnitTests
|
||||
|
@ -72,6 +74,21 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
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]
|
||||
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
|
||||
{
|
||||
readonly Func<object, BindableObject, DataTemplate> _func;
|
||||
|
|
|
@ -223,9 +223,9 @@ namespace Xamarin.Forms
|
|||
{
|
||||
if (e.OldStartingIndex == -1)
|
||||
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;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Xamarin.Forms
|
|||
{
|
||||
protected HandlerAttribute(Type handler, Type target, Type[] supportedVisuals = null)
|
||||
{
|
||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualRendererMarker.Default) };
|
||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualMarker.DefaultVisual) };
|
||||
TargetType = target;
|
||||
HandlerType = handler;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,31 @@ namespace Xamarin.Forms.Internals
|
|||
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)
|
||||
{
|
||||
return self.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace Xamarin.Forms.Internals
|
|||
public class Registrar<TRegistrable> where TRegistrable : class
|
||||
{
|
||||
readonly Dictionary<Type, Dictionary<Type, Type>> _handlers = new Dictionary<Type, Dictionary<Type, Type>>();
|
||||
static Type _defaultVisualType = typeof(VisualRendererMarker.Default);
|
||||
static Type _materialVisualType = typeof(VisualRendererMarker.Material);
|
||||
static Type _defaultVisualType = typeof(VisualMarker.DefaultVisual);
|
||||
static Type _materialVisualType = typeof(VisualMarker.MaterialVisual);
|
||||
|
||||
static Type[] _defaultVisualRenderers = new[] { _defaultVisualType };
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ namespace Xamarin.Forms
|
|||
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)
|
||||
{
|
||||
Type = type;
|
||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualRendererMarker.Default) };
|
||||
SupportedVisuals = supportedVisuals ?? new[] { typeof(VisualMarker.DefaultVisual) };
|
||||
}
|
||||
|
||||
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;
|
||||
if (xfExtendedTypeConverter != null)
|
||||
return value = xfExtendedTypeConverter.ConvertFromInvariantString(str, serviceProvider);
|
||||
if (xfTypeConverter != null)
|
||||
return value = xfTypeConverter.ConvertFromInvariantString(str);
|
||||
if (xfTypeConverter != null) {
|
||||
try {
|
||||
return value = xfTypeConverter.ConvertFromInvariantString(str);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new XamlParseException("Type conversion failed", serviceProvider, e);
|
||||
}
|
||||
}
|
||||
var converterType = converter?.GetType();
|
||||
if (converterType != null)
|
||||
{
|
||||
|
|
|
@ -3,11 +3,8 @@ using System.ComponentModel;
|
|||
using CoreGraphics;
|
||||
using MaterialComponents;
|
||||
using UIKit;
|
||||
using Xamarin.Forms;
|
||||
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
|
||||
{
|
||||
public class MaterialStepperRenderer : ViewRenderer<Stepper, MaterialStepper>
|
||||
|
|
|
@ -15,12 +15,13 @@ using Xamarin.Forms;
|
|||
[assembly: AssemblyVersion("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.Button), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialButtonRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialEntryRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialFrameRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialProgressBarRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialSliderRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialTimePickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialPickerRenderer), new[] { typeof(VisualRendererMarker.Material) })]
|
||||
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialDatePickerRenderer), 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(VisualMarker.MaterialVisual) })]
|
||||
[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(VisualMarker.MaterialVisual) })]
|
||||
[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(VisualMarker.MaterialVisual) })]
|
||||
[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(VisualMarker.MaterialVisual) })]
|
||||
[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 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
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ using AColor = Android.Graphics.Color;
|
|||
using AView = Android.Views.View;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
|||
using Xamarin.Forms;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ using Android.Widget;
|
|||
using Xamarin.Forms;
|
||||
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
|
||||
{
|
||||
public sealed class MaterialEntryRenderer : EntryRendererBase<MaterialFormsTextInputLayout>
|
||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
|||
using AView = Android.Views.View;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
|||
using Xamarin.Forms;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
|||
using AProgressBar = Android.Widget.ProgressBar;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ using Xamarin.Forms.Platform.Android.FastRenderers;
|
|||
using Xamarin.Forms.Platform.Android.Material;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ using Xamarin.Forms.Platform.Android.Material;
|
|||
using AButton = Android.Widget.Button;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using Android.Widget;
|
|||
using Xamarin.Forms;
|
||||
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
|
||||
{
|
||||
|
|
|
@ -5,7 +5,11 @@ namespace Xamarin.Forms
|
|||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
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)]
|
||||
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)]
|
||||
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)]
|
||||
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
|
||||
void InitializeMainPage()
|
||||
{
|
||||
MainPage = new ContentPage()
|
||||
/*MainPage = new ContentPage()
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче