[Visual] Visual xaml and Visual registrations (#5304)
authorShane Neuville <shane94@hotmail.com>
Mon, 25 Feb 2019 20:54:02 +0000 (13:54 -0700)
committerGitHub <noreply@github.com>
Mon, 25 Feb 2019 20:54:02 +0000 (13:54 -0700)
* [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

31 files changed:
Xamarin.Forms.Core.Design/AttributeTableBuilder.cs
Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs [new file with mode: 0644]
Xamarin.Forms.Core.Design/Xamarin.Forms.Core.Design.csproj
Xamarin.Forms.Core/HandlerAttribute.cs
Xamarin.Forms.Core/ReflectionExtensions.cs
Xamarin.Forms.Core/Registrar.cs
Xamarin.Forms.Core/RenderWithAttribute.cs
Xamarin.Forms.Core/Visual.cs [deleted file]
Xamarin.Forms.Core/Visuals/IVisual.cs [new file with mode: 0644]
Xamarin.Forms.Core/Visuals/VisualAttribute.cs [new file with mode: 0644]
Xamarin.Forms.Core/Visuals/VisualMarker.cs [new file with mode: 0644]
Xamarin.Forms.Core/Visuals/VisualTypeConverter.cs [new file with mode: 0644]
Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs
Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs
Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs
Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs
Xamarin.Forms.Platform.GTK/ExportRendererAttribute.cs
Xamarin.Forms.Platform.Tizen/ExportRendererAttribute.cs
Xamarin.Forms.Platform.UAP/ExportRendererAttribute.cs
Xamarin.Forms.Platform.WPF/ExportRendererAttribute.cs
Xamarin.Forms.Sandbox/App.StartHere.cs
Xamarin.Forms.Sandbox/MainPage.xaml [new file with mode: 0644]
Xamarin.Forms.Sandbox/MainPage.xaml.cs [new file with mode: 0644]

index 16ecc1c..69b2563 100644 (file)
@@ -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 (),
diff --git a/Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs b/Xamarin.Forms.Core.Design/VisualDesignTypeConverter.cs
new file mode 100644 (file)
index 0000000..67f8950
--- /dev/null
@@ -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;
+               }
+       }
+}
\ No newline at end of file
index 9343c21..21c871f 100644 (file)
@@ -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" />
index fe8e7f9..a34f009 100644 (file)
@@ -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;
                }
index c2b8082..fd47061 100644 (file)
@@ -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());
index 8962056..cdb5188 100644 (file)
@@ -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 };
 
index 72a5170..9a38e1d 100644 (file)
@@ -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 (file)
index 65b2ce1..0000000
+++ /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 (file)
index 0000000..76af4ea
--- /dev/null
@@ -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 (file)
index 0000000..43d6017
--- /dev/null
@@ -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 (file)
index 0000000..edd57ba
--- /dev/null
@@ -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 (file)
index 0000000..051d446
--- /dev/null
@@ -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<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)
+               {
+                       foreach (var type in assembly.GetExportedTypes())
+                               if (typeof(IVisual).IsAssignableFrom(type) && type != typeof(IVisual))
+                                       Register(type, mappings);
+               }
+
+               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)}");
+               }
+       }
+}
\ No newline at end of file
index 2839737..e3e9c55 100644 (file)
@@ -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>
index ec47abd..5c949c1 100644 (file)
@@ -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
index d58ad5e..7d00344 100644 (file)
@@ -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
 {
index e0102e0..4cf98b4 100644 (file)
@@ -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
 {
index e6ac79e..dec29bb 100644 (file)
@@ -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
 {
index ff71648..c2ac95b 100644 (file)
@@ -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>
index ee39dec..f1f9c19 100644 (file)
@@ -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
 {
index 09c7924..aaa3188 100644 (file)
@@ -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
 {
index 9e5b821..7ec0348 100644 (file)
@@ -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
 {
index 72d0d60..9f9fcf3 100644 (file)
@@ -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
 {
index e396f1d..7eede34 100644 (file)
@@ -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
 {
index f251261..a3c6eac 100644 (file)
@@ -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
 {
index e460244..bd8940d 100644 (file)
@@ -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)
                {
                }
        }
index 9af8019..4e1e193 100644 (file)
@@ -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)
                {
                }
        }
index 2f5c06c..ff890fc 100644 (file)
@@ -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)
                {
                }
        }
index 1097a76..937ae83 100644 (file)
@@ -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)
                {
                }
        }
index 0497f11..20b21e5 100644 (file)
@@ -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 (file)
index 0000000..0f0af41
--- /dev/null
@@ -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>
\ No newline at end of file
diff --git a/Xamarin.Forms.Sandbox/MainPage.xaml.cs b/Xamarin.Forms.Sandbox/MainPage.xaml.cs
new file mode 100644 (file)
index 0000000..84d196f
--- /dev/null
@@ -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();
+               }
+       }
+}
\ No newline at end of file