Encapsulate native control registration

This commit is contained in:
Steve Sanderson 2019-08-22 13:31:21 +01:00 коммит произвёл Eilon Lipton
Родитель b4f31e48a4
Коммит 2ca18fcc63
13 изменённых файлов: 43 добавлений и 55 удалений

Просмотреть файл

@ -9,19 +9,23 @@ namespace Blaxamarin.Framework.Elements
{
static Button()
{
BlelementAdapter.KnownElements.Add(typeof(Button).FullName, new ComponentControlFactoryFunc<Element>((renderer, _) => new BlazorButton(renderer)));
BlelementAdapter.RegisterNativeControlComponent<Button>(
renderer => new BlazorButton(renderer));
}
[Parameter] public string Text { get; set; }
[Parameter] public EventCallback OnClick { get; set; }
protected override void RenderAttributes(RenderTreeBuilder builder)
protected override void RenderAttributes(AttributesBuilder builder)
{
base.RenderAttributes(builder);
if (Text != null)
{
builder.AddAttribute(1, nameof(Text), Text);
builder.AddAttribute(nameof(Text), Text);
}
builder.AddAttribute(2, "onclick", OnClick);
builder.AddAttribute("onclick", OnClick);
}
class BlazorButton : Xamarin.Forms.Button, IBlazorNativeControl

Просмотреть файл

@ -1,39 +1,13 @@
using Microsoft.AspNetCore.Components;
using Emblazon;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.RenderTree;
using System;
using Xamarin.Forms;
namespace Blaxamarin.Framework.Elements
{
public abstract class FormsComponentBase : ComponentBase
public abstract class FormsComponentBase : NativeControlComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, GetType().FullName);
RenderAttributes(builder);
RenderContents(builder);
builder.CloseElement();
}
/// <summary>
/// Rendered attributes should use sequence values 1-99.
/// </summary>
/// <param name="builder"></param>
protected virtual void RenderAttributes(RenderTreeBuilder builder)
{
}
/// <summary>
/// Rendered contents should use sequence values 1000+.
/// </summary>
/// <param name="builder"></param>
protected virtual void RenderContents(RenderTreeBuilder builder)
{
}
public static void ApplyAttribute(Element control, ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName)
{
switch (attributeName)

Просмотреть файл

@ -1,6 +1,5 @@
using Emblazon;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.RenderTree;
namespace BlinForms.Framework.Controls
{
@ -8,7 +7,8 @@ namespace BlinForms.Framework.Controls
{
static Button()
{
BlontrolAdapter.KnownElements.Add(typeof(Button).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((renderer, _) => new BlazorButton(renderer)));
BlontrolAdapter.RegisterNativeControlComponent<Button>(
renderer => new BlazorButton(renderer));
}
[Parameter] public string Text { get; set; }

Просмотреть файл

@ -8,7 +8,7 @@ namespace BlinForms.Framework.Controls
{
static Label()
{
BlontrolAdapter.KnownElements.Add(typeof(Label).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((_, __) => new BlazorLabel()));
BlontrolAdapter.RegisterNativeControlComponent<Label, BlazorLabel>();
}
[Parameter] public string Text { get; set; }

Просмотреть файл

@ -7,7 +7,7 @@ namespace BlinForms.Framework.Controls
{
static Panel()
{
BlontrolAdapter.KnownElements.Add(typeof(Panel).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((_, __) => new BlazorPanel()));
BlontrolAdapter.RegisterNativeControlComponent<Panel, BlazorPanel>();
}
[Parameter] public RenderFragment ChildContent { get; set; }

Просмотреть файл

@ -8,7 +8,7 @@ namespace BlinForms.Framework.Controls
{
static SplitContainer()
{
BlontrolAdapter.KnownElements.Add(typeof(SplitContainer).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((_, __) => new BlazorSplitContainer()));
BlontrolAdapter.RegisterNativeControlComponent<SplitContainer, BlazorSplitContainer>();
}
[Parameter] public RenderFragment ChildContent { get; set; }

Просмотреть файл

@ -6,7 +6,8 @@ namespace BlinForms.Framework.Controls
{
static SplitterPanel1()
{
BlontrolAdapter.KnownElements.Add(typeof(SplitterPanel1).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((_, parentControl) => GetSplitterPanel(parentControl, panelNumber: 1)));
BlontrolAdapter.RegisterNativeControlComponent<SplitterPanel1>(
(_, parentControl) => GetSplitterPanel(parentControl, panelNumber: 1));
}
}
}

Просмотреть файл

@ -6,7 +6,8 @@ namespace BlinForms.Framework.Controls
{
static SplitterPanel2()
{
BlontrolAdapter.KnownElements.Add(typeof(SplitterPanel2).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((_, parentControl) => GetSplitterPanel(parentControl, panelNumber: 2)));
BlontrolAdapter.RegisterNativeControlComponent<SplitterPanel2>(
(_, parentControl) => GetSplitterPanel(parentControl, panelNumber: 2));
}
}
}

Просмотреть файл

@ -1,6 +1,5 @@
using Emblazon;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.RenderTree;
using System.Windows.Forms;
namespace BlinForms.Framework.Controls
@ -9,7 +8,8 @@ namespace BlinForms.Framework.Controls
{
static TextBox()
{
BlontrolAdapter.KnownElements.Add(typeof(TextBox).FullName, new ComponentControlFactoryFunc<System.Windows.Forms.Control>((renderer, _) => new BlazorTextBox(renderer)));
BlontrolAdapter.RegisterNativeControlComponent<TextBox>(
renderer => new BlazorTextBox(renderer));
}
[Parameter] public string Text { get; set; }

Просмотреть файл

@ -2,11 +2,11 @@
namespace Emblazon
{
public class ComponentControlFactoryFunc<TNativeComponent> : IComponentControlFactory<TNativeComponent> where TNativeComponent : class
internal class ComponentControlFactory<TNativeComponent> where TNativeComponent : class
{
private readonly Func<EmblazonRenderer<TNativeComponent>, TNativeComponent, TNativeComponent> _callback;
public ComponentControlFactoryFunc(Func<EmblazonRenderer<TNativeComponent>, TNativeComponent, TNativeComponent> callback)
public ComponentControlFactory(Func<EmblazonRenderer<TNativeComponent>, TNativeComponent, TNativeComponent> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}

Просмотреть файл

@ -1,6 +1,6 @@
namespace Emblazon
{
public class ComponentControlFactoryContext<TNativeComponent> where TNativeComponent : class
internal class ComponentControlFactoryContext<TNativeComponent> where TNativeComponent : class
{
public ComponentControlFactoryContext(EmblazonRenderer<TNativeComponent> renderer, TNativeComponent parentControl)
{

Просмотреть файл

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Components.RenderTree;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Emblazon
{
@ -11,9 +12,23 @@ namespace Emblazon
/// </summary>
public abstract class EmblazonAdapter<TNativeComponent> where TNativeComponent : class
{
// TODO: This used to be internal, but now it's public so that BlinForms components can register themselves. How should this work?
public static Dictionary<string, IComponentControlFactory<TNativeComponent>> KnownElements { get; }
= new Dictionary<string, IComponentControlFactory<TNativeComponent>>();
private static Dictionary<string, ComponentControlFactory<TNativeComponent>> KnownElements { get; }
= new Dictionary<string, ComponentControlFactory<TNativeComponent>>();
public static void RegisterNativeControlComponent<TComponent>(Func<EmblazonRenderer<TNativeComponent>, TNativeComponent, TNativeComponent> factory) where TComponent: NativeControlComponentBase
{
KnownElements.Add(typeof(TComponent).FullName, new ComponentControlFactory<TNativeComponent>(factory));
}
public static void RegisterNativeControlComponent<TComponent>(Func<EmblazonRenderer<TNativeComponent>, TNativeComponent> factory) where TComponent : NativeControlComponentBase
{
KnownElements.Add(typeof(TComponent).FullName, new ComponentControlFactory<TNativeComponent>((renderer, _) => factory(renderer)));
}
public static void RegisterNativeControlComponent<TComponent, TControl>() where TComponent : NativeControlComponentBase where TControl : TNativeComponent, new()
{
RegisterNativeControlComponent<TComponent>((_, __) => new TControl());
}
public EmblazonAdapter()
{

Просмотреть файл

@ -1,7 +0,0 @@
namespace Emblazon
{
public interface IComponentControlFactory<TNativeComponent> where TNativeComponent : class
{
TNativeComponent CreateControl(ComponentControlFactoryContext<TNativeComponent> context);
}
}