From 432adc624dc1ad4441510b0d5eab1fd3c54c830b Mon Sep 17 00:00:00 2001 From: Jeremy Marcus Date: Mon, 25 Feb 2019 14:44:00 -0500 Subject: [PATCH 1/6] Update BindableLayout.cs to fix #5213 (#5243) - fixes #5213 * Add Test for BindableLayout RemoveAll * Update BindableLayout.cs to fix RemoveAll exception * Missing using statements --- .../BindableLayoutTests.cs | 38 +++++++++++++++++++ Xamarin.Forms.Core/BindableLayout.cs | 4 +- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Xamarin.Forms.Core.UnitTests/BindableLayoutTests.cs b/Xamarin.Forms.Core.UnitTests/BindableLayoutTests.cs index 60532c971..e2a6ddcab 100644 --- a/Xamarin.Forms.Core.UnitTests/BindableLayoutTests.cs +++ b/Xamarin.Forms.Core.UnitTests/BindableLayoutTests.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(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 : ObservableCollection + { + public ObservableRangeCollection(IEnumerable collection) + : base(collection) + { + } + + public void RemoveAll() + { + CheckReentrancy(); + + var changedItems = new List(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 _func; diff --git a/Xamarin.Forms.Core/BindableLayout.cs b/Xamarin.Forms.Core/BindableLayout.cs index 271baf20b..228071e21 100644 --- a/Xamarin.Forms.Core/BindableLayout.cs +++ b/Xamarin.Forms.Core/BindableLayout.cs @@ -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; From 16aa48fb1e6af84ccaf97e723dc3ed5602a30106 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Mon, 25 Feb 2019 13:54:02 -0700 Subject: [PATCH 2/6] [Visual] Visual xaml and Visual registrations (#5304) * [visual] add intellisense popups for visual * Add visual registrations into type converter * combine VisualMarker and VisualRendererMarker * remove visual from class name for intellisense * set Match Parent to internal * Remove register code and just scan assemblies * [Visual] Add Visual Attribute and some additional attribute checks * remove registrar changes * renamed to specific VisualTypes * - move check up to LINQ statement * Make sure the other platforms can create visuals * fix renderer names * move stepper renderer * rename converter --- .../AttributeTableBuilder.cs | 6 +- .../VisualDesignTypeConverter.cs | 64 ++++++++++ .../Xamarin.Forms.Core.Design.csproj | 1 + Xamarin.Forms.Core/HandlerAttribute.cs | 2 +- Xamarin.Forms.Core/ReflectionExtensions.cs | 25 ++++ Xamarin.Forms.Core/Registrar.cs | 4 +- Xamarin.Forms.Core/RenderWithAttribute.cs | 4 +- Xamarin.Forms.Core/Visual.cs | 59 --------- Xamarin.Forms.Core/Visuals/IVisual.cs | 7 ++ Xamarin.Forms.Core/Visuals/VisualAttribute.cs | 19 +++ Xamarin.Forms.Core/Visuals/VisualMarker.cs | 30 +++++ .../Visuals/VisualTypeConverter.cs | 114 ++++++++++++++++++ .../MaterialStepperRenderer.cs | 3 - .../Properties/AssemblyInfo.cs | 19 +-- .../MaterialActivityIndicatorRenderer.cs | 2 +- .../Material/MaterialButtonRenderer.cs | 2 +- .../Material/MaterialDatePickerRenderer.cs | 2 +- .../Material/MaterialEntryRenderer.cs | 2 +- .../Material/MaterialFrameRenderer.cs | 2 +- .../Material/MaterialPickerRenderer.cs | 2 +- .../Material/MaterialProgressBarRenderer.cs | 2 +- .../Material/MaterialSliderRenderer.cs | 2 +- .../Material/MaterialStepperRenderer.cs | 2 +- .../Material/MaterialTimePickerRenderer.cs | 2 +- .../ExportRendererAttribute.cs | 6 +- .../ExportRendererAttribute.cs | 6 +- .../ExportRendererAttribute.cs | 6 +- .../ExportRendererAttribute.cs | 6 +- Xamarin.Forms.Sandbox/App.StartHere.cs | 4 +- Xamarin.Forms.Sandbox/MainPage.xaml | 10 ++ Xamarin.Forms.Sandbox/MainPage.xaml.cs | 20 +++ 31 files changed, 343 insertions(+), 92 deletions(-) create mode 100644 Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs delete mode 100644 Xamarin.Forms.Core/Visual.cs create mode 100644 Xamarin.Forms.Core/Visuals/IVisual.cs create mode 100644 Xamarin.Forms.Core/Visuals/VisualAttribute.cs create mode 100644 Xamarin.Forms.Core/Visuals/VisualMarker.cs create mode 100644 Xamarin.Forms.Core/Visuals/VisualTypeConverter.cs create mode 100644 Xamarin.Forms.Sandbox/MainPage.xaml create mode 100644 Xamarin.Forms.Sandbox/MainPage.xaml.cs diff --git a/Xamarin.Forms.Core.Design/AttributeTableBuilder.cs b/Xamarin.Forms.Core.Design/AttributeTableBuilder.cs index 16ecc1c8c..69b256343 100644 --- a/Xamarin.Forms.Core.Design/AttributeTableBuilder.cs +++ b/Xamarin.Forms.Core.Design/AttributeTableBuilder.cs @@ -35,6 +35,10 @@ namespace Xamarin.Forms.Core.Design new System.ComponentModel.TypeConverterAttribute (typeof (NonExclusiveEnumConverter)))); } + 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 (), diff --git a/Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs b/Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs new file mode 100644 index 000000000..67f89503d --- /dev/null +++ b/Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs @@ -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(); + 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; + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Core.Design/Xamarin.Forms.Core.Design.csproj b/Xamarin.Forms.Core.Design/Xamarin.Forms.Core.Design.csproj index 9343c2192..21c871f1f 100644 --- a/Xamarin.Forms.Core.Design/Xamarin.Forms.Core.Design.csproj +++ b/Xamarin.Forms.Core.Design/Xamarin.Forms.Core.Design.csproj @@ -50,6 +50,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/Xamarin.Forms.Core/HandlerAttribute.cs b/Xamarin.Forms.Core/HandlerAttribute.cs index fe8e7f9eb..a34f0099c 100644 --- a/Xamarin.Forms.Core/HandlerAttribute.cs +++ b/Xamarin.Forms.Core/HandlerAttribute.cs @@ -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; } diff --git a/Xamarin.Forms.Core/ReflectionExtensions.cs b/Xamarin.Forms.Core/ReflectionExtensions.cs index c2b8082bf..fd470613f 100644 --- a/Xamarin.Forms.Core/ReflectionExtensions.cs +++ b/Xamarin.Forms.Core/ReflectionExtensions.cs @@ -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()); diff --git a/Xamarin.Forms.Core/Registrar.cs b/Xamarin.Forms.Core/Registrar.cs index 896205600..cdb5188bb 100644 --- a/Xamarin.Forms.Core/Registrar.cs +++ b/Xamarin.Forms.Core/Registrar.cs @@ -19,8 +19,8 @@ namespace Xamarin.Forms.Internals public class Registrar where TRegistrable : class { readonly Dictionary> _handlers = new Dictionary>(); - 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 }; diff --git a/Xamarin.Forms.Core/RenderWithAttribute.cs b/Xamarin.Forms.Core/RenderWithAttribute.cs index 72a51702a..9a38e1d26 100644 --- a/Xamarin.Forms.Core/RenderWithAttribute.cs +++ b/Xamarin.Forms.Core/RenderWithAttribute.cs @@ -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; } diff --git a/Xamarin.Forms.Core/Visual.cs b/Xamarin.Forms.Core/Visual.cs deleted file mode 100644 index 65b2ce18d..000000000 --- a/Xamarin.Forms.Core/Visual.cs +++ /dev/null @@ -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)}"); - } - } -} \ No newline at end of file diff --git a/Xamarin.Forms.Core/Visuals/IVisual.cs b/Xamarin.Forms.Core/Visuals/IVisual.cs new file mode 100644 index 000000000..76af4eab2 --- /dev/null +++ b/Xamarin.Forms.Core/Visuals/IVisual.cs @@ -0,0 +1,7 @@ +namespace Xamarin.Forms +{ + [TypeConverter(typeof(VisualTypeConverter))] + public interface IVisual + { + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Core/Visuals/VisualAttribute.cs b/Xamarin.Forms.Core/Visuals/VisualAttribute.cs new file mode 100644 index 000000000..43d6017ac --- /dev/null +++ b/Xamarin.Forms.Core/Visuals/VisualAttribute.cs @@ -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; } + } +} diff --git a/Xamarin.Forms.Core/Visuals/VisualMarker.cs b/Xamarin.Forms.Core/Visuals/VisualMarker.cs new file mode 100644 index 000000000..edd57ba1d --- /dev/null +++ b/Xamarin.Forms.Core/Visuals/VisualMarker.cs @@ -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() { } } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Core/Visuals/VisualTypeConverter.cs b/Xamarin.Forms.Core/Visuals/VisualTypeConverter.cs new file mode 100644 index 000000000..051d44627 --- /dev/null +++ b/Xamarin.Forms.Core/Visuals/VisualTypeConverter.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Xamarin.Forms.Internals; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms +{ + [Xaml.TypeConversion(typeof(IVisual))] + public class VisualTypeConverter : TypeConverter + { + static Dictionary _visualTypeMappings; + void InitMappings() + { + var mappings = new Dictionary(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 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 mappings) + { + foreach (var type in assembly.GetExportedTypes()) + if (typeof(IVisual).IsAssignableFrom(type) && type != typeof(IVisual)) + Register(type, mappings); + } + + static void Register(Type visual, Dictionary 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)}"); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs index 283973734..e3e9c554a 100644 --- a/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs @@ -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 diff --git a/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs b/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs index ec47abd52..5c949c147 100644 --- a/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs +++ b/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs @@ -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) })] \ No newline at end of file +[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) })] \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs index d58ad5ec6..7d00344c8 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs index e0102e0cd..4cf98b4c3 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs index e6ac79e18..dec29bb08 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs index ff7164899..c2ac95b3f 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs @@ -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 diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs index ee39dec50..f1f9c193d 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs index 09c792484..aaa3188fd 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs index 9e5b82137..7ec0348b5 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs index 72d0d60a5..9f9fcf322 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs index e396f1d18..7eede342d 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs index f25126190..a3c6eac8b 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs @@ -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 { diff --git a/Xamarin.Forms.Platform.GTK/ExportRendererAttribute.cs b/Xamarin.Forms.Platform.GTK/ExportRendererAttribute.cs index e460244a4..bd8940d24 100644 --- a/Xamarin.Forms.Platform.GTK/ExportRendererAttribute.cs +++ b/Xamarin.Forms.Platform.GTK/ExportRendererAttribute.cs @@ -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) { } } diff --git a/Xamarin.Forms.Platform.Tizen/ExportRendererAttribute.cs b/Xamarin.Forms.Platform.Tizen/ExportRendererAttribute.cs index 9af8019f7..4e1e19321 100644 --- a/Xamarin.Forms.Platform.Tizen/ExportRendererAttribute.cs +++ b/Xamarin.Forms.Platform.Tizen/ExportRendererAttribute.cs @@ -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) { } } diff --git a/Xamarin.Forms.Platform.UAP/ExportRendererAttribute.cs b/Xamarin.Forms.Platform.UAP/ExportRendererAttribute.cs index 2f5c06c4f..ff890fc84 100644 --- a/Xamarin.Forms.Platform.UAP/ExportRendererAttribute.cs +++ b/Xamarin.Forms.Platform.UAP/ExportRendererAttribute.cs @@ -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) { } } diff --git a/Xamarin.Forms.Platform.WPF/ExportRendererAttribute.cs b/Xamarin.Forms.Platform.WPF/ExportRendererAttribute.cs index 1097a7636..937ae838f 100644 --- a/Xamarin.Forms.Platform.WPF/ExportRendererAttribute.cs +++ b/Xamarin.Forms.Platform.WPF/ExportRendererAttribute.cs @@ -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) { } } diff --git a/Xamarin.Forms.Sandbox/App.StartHere.cs b/Xamarin.Forms.Sandbox/App.StartHere.cs index 0497f1157..20b21e55d 100644 --- a/Xamarin.Forms.Sandbox/App.StartHere.cs +++ b/Xamarin.Forms.Sandbox/App.StartHere.cs @@ -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(); } } } diff --git a/Xamarin.Forms.Sandbox/MainPage.xaml b/Xamarin.Forms.Sandbox/MainPage.xaml new file mode 100644 index 000000000..0f0af41b3 --- /dev/null +++ b/Xamarin.Forms.Sandbox/MainPage.xaml @@ -0,0 +1,10 @@ + + + + +