forked from dotnet/MobileBlazorBindings
-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for ShellContent.ContentTemplate property (#94)
- Loading branch information
1 parent
637748e
commit 78ec41e
Showing
8 changed files
with
243 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/BlazorBindings.Maui/Elements/Internal/DataTemplates/SyncControlTemplateItemsComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using BlazorBindings.Core; | ||
using BlazorBindings.Maui.Elements.Internal; | ||
using Microsoft.AspNetCore.Components; | ||
using System; | ||
using System.Linq; | ||
using MC = Microsoft.Maui.Controls; | ||
|
||
namespace BlazorBindings.Maui.Elements.DataTemplates | ||
{ | ||
/// <summary> | ||
/// Unlike <see cref="ControlTemplateItemsComponent{T}"/>, this DataTemplate component does not use a wrapping element. | ||
/// This makes it possible to use when returning a View from template is not an option. | ||
/// However, it requires a DataTemplate to render synchronously, which does not always work with Blazor. | ||
/// </summary> | ||
internal class SyncControlTemplateItemsComponent<T> : NativeControlComponentBase, IMauiContainerElementHandler, INonChildContainerElement | ||
where T : MC.BindableObject | ||
{ | ||
protected override RenderFragment GetChildContent() | ||
{ | ||
return builder => | ||
{ | ||
for (int i = 0; i < _count; i++) | ||
{ | ||
builder.OpenComponent<RootContainerComponent>(1); | ||
builder.AddAttribute(2, nameof(RootContainerComponent.ChildContent), Template); | ||
builder.AddComponentReferenceCapture(3, c => _lastRootContainer = (RootContainerComponent)c); | ||
builder.CloseComponent(); | ||
} | ||
}; | ||
} | ||
|
||
[Parameter] public Action<T, MC.ControlTemplate> SetControlTemplateAction { get; set; } | ||
[Parameter] public Action<T, MC.DataTemplate> SetDataTemplateAction { get; set; } | ||
[Parameter] public RenderFragment Template { get; set; } | ||
|
||
private RootContainerComponent _lastRootContainer; | ||
private int _count; | ||
|
||
private Microsoft.Maui.IView AddTemplateRoot() | ||
{ | ||
_count++; | ||
StateHasChanged(); | ||
|
||
var rootElement = _lastRootContainer?.Elements?.FirstOrDefault() | ||
?? throw new InvalidOperationException("Template root control is supposed to be rendered at this point."); | ||
_lastRootContainer = null; | ||
|
||
return (Microsoft.Maui.IView)rootElement; | ||
} | ||
|
||
void INonPhysicalChild.SetParent(object parentElement) | ||
{ | ||
var parent = (T)parentElement; | ||
|
||
if (SetControlTemplateAction != null) | ||
{ | ||
var controlTemplate = new MC.ControlTemplate(AddTemplateRoot); | ||
SetControlTemplateAction(parent, controlTemplate); | ||
} | ||
|
||
if (SetDataTemplateAction != null) | ||
{ | ||
var dataTemplate = new MC.DataTemplate(AddTemplateRoot); | ||
SetDataTemplateAction(parent, dataTemplate); | ||
} | ||
} | ||
|
||
void INonPhysicalChild.RemoveFromParent(object parentElement) { } | ||
|
||
void IElementHandler.ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName) { } | ||
|
||
void IMauiContainerElementHandler.AddChild(MC.BindableObject child, int physicalSiblingIndex) { } | ||
void IMauiContainerElementHandler.RemoveChild(MC.BindableObject child) { } | ||
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) => -1; | ||
MC.BindableObject IMauiElementHandler.ElementControl => null; | ||
object IElementHandler.TargetElement => null; | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/BlazorBindings.Maui/Elements/Internal/RootContainerComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using BlazorBindings.Core; | ||
using Microsoft.AspNetCore.Components; | ||
using System; | ||
using System.Collections.Generic; | ||
using MC = Microsoft.Maui.Controls; | ||
|
||
namespace BlazorBindings.Maui.Elements.Internal | ||
{ | ||
internal class RootContainerComponent : NativeControlComponentBase, IMauiContainerElementHandler, INonChildContainerElement | ||
{ | ||
[Parameter] public RenderFragment ChildContent { get; set; } | ||
protected override RenderFragment GetChildContent() => ChildContent; | ||
|
||
public List<MC.BindableObject> Elements { get; } = new List<MC.BindableObject>(); | ||
|
||
void IMauiContainerElementHandler.AddChild(MC.BindableObject child, int physicalSiblingIndex) | ||
{ | ||
var index = Math.Min(physicalSiblingIndex, Elements.Count); | ||
Elements.Insert(index, child); | ||
} | ||
|
||
void IMauiContainerElementHandler.RemoveChild(MC.BindableObject child) | ||
{ | ||
Elements.Remove(child); | ||
} | ||
|
||
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) | ||
{ | ||
return Elements.IndexOf(child); | ||
} | ||
|
||
// Because this is a 'fake' container element, all matters related to physical trees | ||
// should be no-ops. | ||
MC.BindableObject IMauiElementHandler.ElementControl => null; | ||
object IElementHandler.TargetElement => null; | ||
void IElementHandler.ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName) { } | ||
void INonPhysicalChild.SetParent(object parentElement) { } | ||
void INonPhysicalChild.RemoveFromParent(object parentElement) { } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters