Blaxamarin updates: Have file represent ContentPages, add StackLayout
- Redid root Blaxamarin components to represent a ContentPage, which should make it more generically useful in apps - Added StackLayout component - But... found a bug in Emblazon where siblingIndex of elements is always 0 (applies to BlinForms and Blaxamarin, but has a more negative effect in Blaxamarin where sibling order always matters, whereas in BlinForms it rarely matters)
This commit is contained in:
Родитель
66ed7e31c1
Коммит
bbc0e4a60f
|
@ -6,19 +6,22 @@ namespace Blaxamarin.Framework
|
|||
{
|
||||
public static class Blaxamarin
|
||||
{
|
||||
public static void Run<T>(Application app) where T : IComponent
|
||||
public static ContentPage Run<T>() where T : IComponent
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||
|
||||
var renderer = new BlaxamarinRenderer(serviceProvider, app);
|
||||
renderer.Dispatcher.InvokeAsync(async () =>
|
||||
var renderer = new BlaxamarinRenderer(serviceProvider);
|
||||
var result = renderer.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
await renderer.AddComponent<T>();
|
||||
|
||||
// TODO: Do we need anything similar to what BlinForms does?
|
||||
//Application.Run(renderer.RootForm);
|
||||
|
||||
return renderer.ContentPage;
|
||||
});
|
||||
return result.GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,12 @@ namespace Blaxamarin.Framework
|
|||
{
|
||||
public class BlaxamarinRenderer : EmblazonRenderer<Element>
|
||||
{
|
||||
public BlaxamarinRenderer(Microsoft.Extensions.DependencyInjection.ServiceProvider serviceProvider, Application app)
|
||||
public BlaxamarinRenderer(Microsoft.Extensions.DependencyInjection.ServiceProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
App = app;
|
||||
}
|
||||
|
||||
public Application App { get; }
|
||||
public ContentPage ContentPage { get; } = new ContentPage();
|
||||
|
||||
protected override void InitializeRootAdapter(EmblazonAdapter<Element> adapter)
|
||||
{
|
||||
|
@ -27,9 +26,9 @@ namespace Blaxamarin.Framework
|
|||
// Dock = DockStyle.Fill,
|
||||
//};
|
||||
|
||||
adapter.TargetControl = App;
|
||||
adapter.TargetControl = new ContentView();
|
||||
|
||||
//RootForm.Controls.Add(adapter.TargetControl);
|
||||
ContentPage.Content = adapter.TargetControl as View;
|
||||
}
|
||||
|
||||
protected override void HandleException(Exception exception)
|
||||
|
|
|
@ -35,49 +35,57 @@ namespace Blaxamarin.Framework
|
|||
{
|
||||
// TODO: What is the set of types that support child elements? Do they all need to be special-cased here? (Maybe...)
|
||||
|
||||
if (parentControl is Layout<View> parentAsLayout)
|
||||
switch (parentControl)
|
||||
{
|
||||
var childAsView = childControl as View;
|
||||
case Layout<View> parentAsLayout:
|
||||
{
|
||||
var childAsView = childControl as View;
|
||||
|
||||
if (siblingIndex <= parentAsLayout.Children.Count)
|
||||
{
|
||||
// WinForms ControlCollection doesn't support Insert(), so add the new child at the end,
|
||||
// and then re-order the collection to move the control to the correct index.
|
||||
parentAsLayout.Children.Insert(siblingIndex, childAsView);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"WARNING: {nameof(AddChildControl)} called with {nameof(siblingIndex)}={siblingIndex}, but parentAsLayout.Children.Count={parentAsLayout.Children.Count}");
|
||||
parentAsLayout.Children.Add(childAsView);
|
||||
}
|
||||
}
|
||||
else if (parentControl is Application parentAsApp)
|
||||
{
|
||||
if (parentAsApp.MainPage != null)
|
||||
{
|
||||
Debug.Fail($"Application already has MainPage set; cannot set {parentAsApp.GetType().FullName}'s MainPage to {childControl.GetType().FullName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (childControl is Page childControlAsPage)
|
||||
{
|
||||
parentAsApp.MainPage = childControlAsPage;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Do we need a BlelementAdapter representing the dummy ContentPage? Or should the Razor page be a ContentPage somehow?
|
||||
var dummyView = new ContentPage
|
||||
if (siblingIndex <= parentAsLayout.Children.Count)
|
||||
{
|
||||
Content = childControl as View
|
||||
};
|
||||
parentAsApp.MainPage = dummyView;
|
||||
//Debug.Fail($"Application MainPage must be a Page; cannot set {parentAsApp.GetType().FullName}'s MainPage to {childControl.GetType().FullName}");
|
||||
parentAsLayout.Children.Insert(siblingIndex, childAsView);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"WARNING: {nameof(AddChildControl)} called with {nameof(siblingIndex)}={siblingIndex}, but parentAsLayout.Children.Count={parentAsLayout.Children.Count}");
|
||||
parentAsLayout.Children.Add(childAsView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Fail($"Don't know how to handle parent control type {parentControl.GetType().FullName} in order to add child {childControl.GetType().FullName}");
|
||||
break;
|
||||
case ContentView parentAsContentView:
|
||||
{
|
||||
var childAsView = childControl as View;
|
||||
parentAsContentView.Content = childAsView;
|
||||
}
|
||||
break;
|
||||
case Application parentAsApp:
|
||||
{
|
||||
if (parentAsApp.MainPage != null)
|
||||
{
|
||||
Debug.Fail($"Application already has MainPage set; cannot set {parentAsApp.GetType().FullName}'s MainPage to {childControl.GetType().FullName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (childControl is Page childControlAsPage)
|
||||
{
|
||||
parentAsApp.MainPage = childControlAsPage;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Do we need a BlelementAdapter representing the dummy ContentPage? Or should the Razor page be a ContentPage somehow?
|
||||
var dummyView = new ContentPage
|
||||
{
|
||||
Content = childControl as View
|
||||
};
|
||||
parentAsApp.MainPage = dummyView;
|
||||
//Debug.Fail($"Application MainPage must be a Page; cannot set {parentAsApp.GetType().FullName}'s MainPage to {childControl.GetType().FullName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.Fail($"Don't know how to handle parent element type {parentControl.GetType().FullName} in order to add child {childControl.GetType().FullName}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
using Emblazon;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Blaxamarin.Framework.Elements
|
||||
{
|
||||
public class StackLayout : FormsComponentBase
|
||||
{
|
||||
static StackLayout()
|
||||
{
|
||||
BlelementAdapter.KnownElements.Add(typeof(StackLayout).FullName, new ComponentControlFactoryFunc<Element>((_, __) => new BlazorStackLayout()));
|
||||
}
|
||||
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
|
||||
protected override void RenderContents(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.AddContent(1000, ChildContent);
|
||||
}
|
||||
|
||||
class BlazorStackLayout : Xamarin.Forms.StackLayout, IBlazorNativeControl
|
||||
{
|
||||
public BlazorStackLayout()
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName)
|
||||
{
|
||||
switch (attributeName)
|
||||
{
|
||||
default:
|
||||
FormsComponentBase.ApplyAttribute(this, attributeEventHandlerId, attributeName, attributeValue, attributeEventUpdatesAttributeName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Xamarin.Forms;
|
||||
using BlaxamarinSample.Services;
|
||||
using BlaxamarinSample.Views;
|
||||
|
||||
namespace BlaxamarinSample
|
||||
{
|
||||
|
@ -15,7 +12,7 @@ namespace BlaxamarinSample
|
|||
|
||||
DependencyService.Register<MockDataStore>();
|
||||
|
||||
Blaxamarin.Framework.Blaxamarin.Run<Blaxample>(this);
|
||||
MainPage = Blaxamarin.Framework.Blaxamarin.Run<Blaxample>();
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
@using Blaxamarin.Framework.Elements
|
||||
|
||||
<Button Text="@("Increment: " + count)" OnClick="@IncrementCount" />
|
||||
|
||||
<StackLayout>
|
||||
<Button Text="@("Increment by 1: " + count)" OnClick="@IncrementCount" />
|
||||
<Button Text="@("Increment by 8: " + count2)" OnClick="@IncrementCount2" />
|
||||
<Button Text="333"></Button>
|
||||
<Button Text="444"></Button>
|
||||
<Button Text="555"></Button>
|
||||
</StackLayout>
|
||||
|
||||
@code {
|
||||
int count = 0;
|
||||
|
@ -10,4 +15,11 @@
|
|||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
int count2 = 0;
|
||||
|
||||
void IncrementCount2()
|
||||
{
|
||||
count2 += 8;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче