From 01dacb47ffc18eaf762efa3bdbb31bfa4635464b Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 27 Jul 2022 04:36:08 -0500 Subject: [PATCH] Update event callback approach --- .../blazor/components/dynamiccomponent.md | 518 +++++++++++++----- 1 file changed, 382 insertions(+), 136 deletions(-) diff --git a/aspnetcore/blazor/components/dynamiccomponent.md b/aspnetcore/blazor/components/dynamiccomponent.md index 7827db230485..b431332ec490 100644 --- a/aspnetcore/blazor/components/dynamiccomponent.md +++ b/aspnetcore/blazor/components/dynamiccomponent.md @@ -90,7 +90,7 @@ In the following example, a Razor component renders a component based on the use In the preceding example: * Component names are used as the option values using the [`nameof` operator](/dotnet/csharp/language-reference/operators/nameof), which returns component names as constant strings. -* The namespace of the app is `BlazorSample`. +* The namespace of the app is `BlazorSample`. Change the namespace to match your app's namespace. ## Pass parameters @@ -118,7 +118,7 @@ The following `RocketLabWithWindowSeat` component (`Shared/RocketLabWithWindowSe In the following example: * Only the `RocketLabWithWindowSeat` component's parameter for a window seat (`WindowSeat`) receives the value of the **`Window Seat`** checkbox. -* The namespace of the app is `BlazorSample`. +* The namespace of the app is `BlazorSample`. Change the namespace to match your app's namespace. * The dynamically-rendered components are shared components in the app's `Shared` folder: * Shown in this article section: `RocketLabWithWindowSeat` (`Shared/RocketLabWithWindowSeat.razor`) * Components shown in the [Example](#example) section earlier in this article: @@ -134,12 +134,29 @@ In the following example: Event callbacks () can be passed to a in its parameter dictionary. -> [!NOTE] -> The example in this section is an extension of the full example shown in the *Pass parameters* section of this article. +`ComponentMetadata.cs`: + +```csharp +public class ComponentMetadata +{ + public string? Name { get; set; } + public Dictionary Parameters { get; set; } = + new Dictionary(); +} +``` + +Implement an event callback parameter () within each dynamically-rendered component. -Implement an event callback parameter () within each dynamically-rendered component: +`Shared/RocketLab2.razor`: ```razor +

Rocket Lab®

+ +

+ Rocket Lab is a registered trademark of + Rocket Lab USA Inc. +

+ @@ -150,88 +167,194 @@ Implement an event callback parameter (SpaceX® -

@message

+

+ SpaceX is a registered trademark of + Space Exploration Technologies Corp. +

+ + @code { - ... - private string? message; - ... - private void ShowDTMessage(MouseEventArgs e) => - message = $"The current DT is: {DateTime.Now}."; + [Parameter] + public EventCallback OnClickCallback { get; set; } } ``` -The parent component passes the parameter with: +`Shared/UnitedLaunchAlliance2.razor`: -* A `string` key equal to the callback method name, `OnClickCallback` in the following example. -* An `object` value created by for the parent callback method, `ShowDTMessage` in the following example. +```razor +

United Launch Alliance®

-```csharp -private Dictionary components = - new() +

+ United Launch Alliance and ULA are registered trademarks of + United Launch Alliance, LLC. +

+ + + +@code { + [Parameter] + public EventCallback OnClickCallback { get; set; } +} +``` + +`Shared/VirginGalactic2.razor`: + +```razor +

Virgin Galactic®

+ +

+ Virgin Galactic is a registered trademark of + Galactic Enterprises, LLC. +

+ + + +@code { + [Parameter] + public EventCallback OnClickCallback { get; set; } +} +``` + +In the following parent component example, the `ShowDTMessage` method assigns a string with the current time to `message`, and the value of `message` is rendered. + +The parent component passes the callback method, `ShowDTMessage` in the parameter dictionary: + +* The `string` key is the callback method's name, `OnClickCallback`. +* The `object` value is created by for the parent callback method, `ShowDTMessage`. Note that the [`this` keyword](/dotnet/csharp/language-reference/keywords/this) isn't supported in C# fields, so a C# property is used for the parameter dictionary. + +**For the following component, change the namespace name of `BlazorSample` in the `OnDropdownChange` method to match your app's namespace.** + +`Pages/DynamicComponentExample3.razor`: + +```razor +@page "/dynamiccomponent-example-3" + +

DynamicComponent Component Example 3

+ +

+ +

+ +@if (selectedType is not null) +{ +
+ +
+} + +

+ @message +

+ +@code { + private Type? selectedType; + private string? message; + + private Dictionary Components { + get { - "RocketLabWithWindowSeat", - new ComponentMetadata + return new Dictionary() { - Name = "Rocket Lab with Window Seat", - Parameters = new() { - { "WindowSeat", false }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "VirginGalactic", - new ComponentMetadata - { - Name = "Virgin Galactic", - Parameters = new() + "RocketLab2", + new ComponentMetadata + { + Name = "Rocket Lab", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "UnitedLaunchAlliance", - new ComponentMetadata - { - Name = "ULA", - Parameters = new() + "VirginGalactic2", + new ComponentMetadata + { + Name = "Virgin Galactic", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "SpaceX", - new ComponentMetadata - { - Name = "SpaceX", - Parameters = new() + "UnitedLaunchAlliance2", + new ComponentMetadata + { + Name = "ULA", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } + "SpaceX2", + new ComponentMetadata + { + Name = "SpaceX", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } } - } + }; } - }; + } + + private void OnDropdownChange(ChangeEventArgs e) + { + selectedType = e.Value?.ToString()?.Length > 0 ? + Type.GetType($"BlazorSample.Shared.{e.Value}") : null; + } + + private void ShowDTMessage(MouseEventArgs e) => + message = $"The current DT is: {DateTime.Now}."; +} ``` ## Avoid catch-all parameters @@ -324,7 +447,7 @@ In the following example, a Razor component renders a component based on the use In the preceding example: * Component names are used as the option values using the [`nameof` operator](/dotnet/csharp/language-reference/operators/nameof), which returns component names as constant strings. -* The namespace of the app is `BlazorSample`. +* The namespace of the app is `BlazorSample`. Change the namespace to match your app's namespace. ## Pass parameters @@ -352,7 +475,7 @@ The following `RocketLabWithWindowSeat` component (`Shared/RocketLabWithWindowSe In the following example: * Only the `RocketLabWithWindowSeat` component's parameter for a window seat (`WindowSeat`) receives the value of the **`Window Seat`** checkbox. -* The namespace of the app is `BlazorSample`. +* The namespace of the app is `BlazorSample`. Change the namespace to match your app's namespace. * The dynamically-rendered components are shared components in the app's `Shared` folder: * Shown in this article section: `RocketLabWithWindowSeat` (`Shared/RocketLabWithWindowSeat.razor`) * Components shown in the [Example](#example) section earlier in this article: @@ -368,12 +491,29 @@ In the following example: Event callbacks () can be passed to a in its parameter dictionary. -> [!NOTE] -> The example in this section is an extension of the full example shown in the *Pass parameters* section of this article. +`ComponentMetadata.cs`: + +```csharp +public class ComponentMetadata +{ + public string? Name { get; set; } + public Dictionary Parameters { get; set; } = + new Dictionary(); +} +``` + +Implement an event callback parameter () within each dynamically-rendered component. -Implement an event callback parameter () within each dynamically-rendered component: +`Shared/RocketLab2.razor`: ```razor +

Rocket Lab®

+ +

+ Rocket Lab is a registered trademark of + Rocket Lab USA Inc. +

+ @@ -384,88 +524,194 @@ Implement an event callback parameter (SpaceX® -

@message

+

+ SpaceX is a registered trademark of + Space Exploration Technologies Corp. +

+ + @code { - ... - private string? message; - ... - private void ShowDTMessage(MouseEventArgs e) => - message = $"The current DT is: {DateTime.Now}."; + [Parameter] + public EventCallback OnClickCallback { get; set; } } ``` -The parent component passes the parameter with: +`Shared/UnitedLaunchAlliance2.razor`: -* A `string` key equal to the callback method name, `OnClickCallback` in the following example. -* An `object` value created by for the parent callback method, `ShowDTMessage` in the following example. +```razor +

United Launch Alliance®

-```csharp -private Dictionary components = - new() +

+ United Launch Alliance and ULA are registered trademarks of + United Launch Alliance, LLC. +

+ + + +@code { + [Parameter] + public EventCallback OnClickCallback { get; set; } +} +``` + +`Shared/VirginGalactic2.razor`: + +```razor +

Virgin Galactic®

+ +

+ Virgin Galactic is a registered trademark of + Galactic Enterprises, LLC. +

+ + + +@code { + [Parameter] + public EventCallback OnClickCallback { get; set; } +} +``` + +In the following parent component example, the `ShowDTMessage` method assigns a string with the current time to `message`, and the value of `message` is rendered. + +The parent component passes the callback method, `ShowDTMessage` in the parameter dictionary: + +* The `string` key is the callback method's name, `OnClickCallback`. +* The `object` value is created by for the parent callback method, `ShowDTMessage`. Note that the [`this` keyword](/dotnet/csharp/language-reference/keywords/this) isn't supported in C# fields, so a C# property is used for the parameter dictionary. + +**For the following component, change the namespace name of `BlazorSample` in the `OnDropdownChange` method to match your app's namespace.** + +`Pages/DynamicComponentExample3.razor`: + +```razor +@page "/dynamiccomponent-example-3" + +

DynamicComponent Component Example 3

+ +

+ +

+ +@if (selectedType is not null) +{ +
+ +
+} + +

+ @message +

+ +@code { + private Type? selectedType; + private string? message; + + private Dictionary Components { + get { - "RocketLabWithWindowSeat", - new ComponentMetadata + return new Dictionary() { - Name = "Rocket Lab with Window Seat", - Parameters = new() { - { "WindowSeat", false }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "VirginGalactic", - new ComponentMetadata - { - Name = "Virgin Galactic", - Parameters = new() + "RocketLab2", + new ComponentMetadata + { + Name = "Rocket Lab", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "UnitedLaunchAlliance", - new ComponentMetadata - { - Name = "ULA", - Parameters = new() + "VirginGalactic2", + new ComponentMetadata + { + Name = "Virgin Galactic", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } - } - } - }, - { - "SpaceX", - new ComponentMetadata - { - Name = "SpaceX", - Parameters = new() + "UnitedLaunchAlliance2", + new ComponentMetadata + { + Name = "ULA", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } + }, { - { "WindowSeat", true }, - { "OnClickCallback", - EventCallback.Factory.Create( - this, ShowDTMessage) } + "SpaceX2", + new ComponentMetadata + { + Name = "SpaceX", + Parameters = + new() + { + { + "OnClickCallback", + EventCallback.Factory.Create( + this, ShowDTMessage) + } + } + } } - } + }; } - }; + } + + private void OnDropdownChange(ChangeEventArgs e) + { + selectedType = e.Value?.ToString()?.Length > 0 ? + Type.GetType($"BlazorSample.Shared.{e.Value}") : null; + } + + private void ShowDTMessage(MouseEventArgs e) => + message = $"The current DT is: {DateTime.Now}."; +} ``` ## Avoid catch-all parameters