diff --git a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableComponentBase.cs b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableComponentBase.cs index 94553801..8d466b33 100644 --- a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableComponentBase.cs +++ b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableComponentBase.cs @@ -25,6 +25,12 @@ namespace AXSharp.Presentation.Blazor.Controls.RenderableContent /// public partial class RenderableComponentBase : ComponentBase, IRenderableComponent, IDisposable { + /// + /// Gets or sets the RenderableContentControl that encapsulates this component. + /// + [Parameter] + public object RccContainer { get; set; } = new Object(); + [Parameter] public int PollingInterval { get; set; } /// diff --git a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor index 55422c8b..3cb897b1 100644 --- a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor +++ b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor @@ -1,9 +1,12 @@ @*This class is view part of RenderableContentControl. It contains UI generation pipeline.*@ @*Call rendering method over context object*@ -
- @RenderComponent(_context) -
+@if (Context != null) +{ +
+ @RenderComponent(Context) +
+} @@ -11,6 +14,9 @@ { private RenderFragment RenderComponent(ITwinElement element) => __builder => { + if (element == null) + return; + // if it is primitive type, just generate if (element is ITwinPrimitive) { diff --git a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor.cs b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor.cs index b9a4a3e6..20f5f58d 100644 --- a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor.cs +++ b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor.Controls/RenderableContent/RenderableContentControl.razor.cs @@ -19,8 +19,10 @@ using AXSharp.Presentation.Blazor.Exceptions; using System.Reflection; using System.ComponentModel; +using System.Globalization; using AXSharp.Connector.ValueTypes; using System.Xml.Linq; +using AXSharp.Connector.Localizations; namespace AXSharp.Presentation.Blazor.Controls.RenderableContent { @@ -42,7 +44,7 @@ public partial class RenderableContentControl : ComponentBase, IDisposable /// Parameter Context accept ITwinElement instance, which is used as base model for UI generation. ///
[Parameter] - public object Context + public ITwinElement Context { get => _context; set @@ -83,6 +85,14 @@ public string Presentation /// [Parameter] public string LayoutClass { get; set; } + + /// + /// Gets or sets parent container containing this renderable content control + /// [!NOTE] This method is used in advanced scenarios it must be set explicitly. + /// + [Parameter] + public ComponentBase ParentContainer { get; set; } + /// /// Parameter LayoutChildrenClass, in which children of layouts will be wrapped. /// @@ -103,10 +113,7 @@ protected override void OnInitialized() { base.OnInitialized(); - if(_context is null) - { - throw new ParameterWrongTypeRendererException(Context.GetType().ToString()); - } + } /// @@ -121,15 +128,15 @@ public void ForceRender() protected override void OnParametersSet() { - Type layoutType = TryLoadLayoutTypeFromProperty(_context); + Type layoutType = TryLoadLayoutTypeFromProperty(Context); if (layoutType == null) { - layoutType = TryLoadLayoutType(_context); + layoutType = TryLoadLayoutType(Context); } if (layoutType != null) MainLayoutType = layoutType; - _groupContainer = TryLoadGroupTypeFromProperty(_context); - if (_groupContainer == null) _groupContainer = TryLoadGroupType(_context); + _groupContainer = TryLoadGroupTypeFromProperty(Context); + if (_groupContainer == null) _groupContainer = TryLoadGroupType(Context); if (String.IsNullOrEmpty(Presentation)) Presentation = ""; _viewModelCache.ResetCounter(); @@ -189,7 +196,16 @@ internal IRenderableComponent ViewLocatorBuilder(Type twinType, ITwinElement twi //if not found, look at predecessor component = ViewLocatorBuilder(twinType.BaseType, twin, presentationName); } - if (component != null) return component; + + if (component != null) + { + if (component is RenderableComponentBase) + { + ((RenderableComponentBase)component).RccContainer = this; + } + + return component; + } } return null; } @@ -224,6 +240,7 @@ private RenderFragment CreatePrimitiveComponent(ITwinPrimitive twinPrimitive, IR __builder.OpenComponent(1, primitiveComponent.GetType()); __builder.AddAttribute(2, "Onliner", twinPrimitive); __builder.AddAttribute(3, "IsReadOnly", HasReadAccess(twinPrimitive)); + __builder.AddAttribute(1, "RccContainer", this); __builder.CloseComponent(); }; @@ -234,6 +251,7 @@ private RenderFragment CreateComplexComponent(ITwinObject twin, IRenderableCompo if (component is IRenderableComplexComponentBase) { __builder.AddAttribute(1, "Component", twin); + __builder.AddAttribute(1, "RccContainer", this); } else if (component is IRenderableViewModelBase) { diff --git a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor/Interfaces/IRenderableComponent.cs b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor/Interfaces/IRenderableComponent.cs index a37fc71e..d4ef6fac 100644 --- a/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor/Interfaces/IRenderableComponent.cs +++ b/src/AXSharp.blazor/src/AXSharp.Presentation.Blazor/Interfaces/IRenderableComponent.cs @@ -22,5 +22,6 @@ public interface IRenderableComponent /// void RemovePolledElements(); + } }