Introducing the PSC #Survey Suite for #Blazor: a runtime component, a drag-and-drop visual #designer, and bulk importers that all speak the same JSON

seen from China
seen from United States
seen from United States

seen from United States

seen from United States

seen from United States

seen from Malaysia
seen from United States

seen from United States
seen from United Kingdom
seen from China

seen from Brunei

seen from United States
seen from United States
seen from Brazil

seen from United States
seen from Kazakhstan
seen from United States
seen from China
seen from China
Introducing the PSC #Survey Suite for #Blazor: a runtime component, a drag-and-drop visual #designer, and bulk importers that all speak the same JSON

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch ⢠No registration required ⢠HD streaming
Tabs control for Blazor
In this new post, I explain how to create and use Tabs control for Blazor Web Assembly and Blazor Server. You have the full code of this component on GitHub.
Anatomy of Tabs
Tabs container attributes
Anatomy of Tabs control for Blazor
AttributeDescriptionTextFilling1This text is displayed on the left hand side of the tabsTextFilling2This text is displayed on the right hand side of the tabs
Tabs container events
Also, Tabs has the following events that you can use.
EventDescriptionOnTabChangedWhen the use click on a new tab, this event is raised. So, you can attach a function to read the new tab object
Tab attributes
AttributeDescriptionTextThe text to display in the tabValueThe value associate to a tab (useful if you have to filter your data)EnabledIs this tab enabled? If not the user canāt click on it. By default is True
How to use it?
First, add the NuGet package in your project. The name of the package is PSC.Blazor.Components.Tabs and the only dependency it has is Microsoft.AspNetCore.Components.Web (>= 5.0.10).
After that, in your wwwroot\index.html or in the hosts file, you have to add a theme (CSS) for your segment control. Obviously, you can create your own theme. So, use this code:
<link href="_content/PSC.Blazor.Components.Tabs/themes/{theme-name}.css" rel="stylesheet" />
Example
<Tabs TextFilling1="@text1" TextFilling2="@text2" OnTabChanged="OnTabChanged"> <Tab Text="Tab 1" Value="Tab1"> <h2>Content Tab 1</h2> <p> This is the content for the Tab 1. It is enabled. </p> </Tab> <Tab Text="Tab 2" Value="Tab2"> <h2>Content Tab 2</h2> <p> This is the content for the Tab 2. It is enabled. </p> </Tab> <Tab Text="Tab 3" Value="Tab3"> <h2>Content Tab 3</h2> <p> This is the content for the Tab 3. It is enabled. </p> </Tab> <Tab Text="Tab 4" Enabled="@IsEnabled" Value="Tab4"> <h2>Content Tab 4</h2> <p> This is the content for the Tab 4. It is disabled if <i>IsEnabled = false</i> </p> </Tab> </Tabs> @code { public string text1 = "Text on the left"; public string text2 = "Text on the right"; public bool IsEnabled = false; public async Task OnTabChanged(Tab tab) { text1 = $"Tab value: {tab.Value}"; text2 = $"Tab text: {tab.Text}"; } }
Themes
Blue
Blue theme
Green
Green theme
Light colors theme
Red
Red theme
Wrap up
So, now we have a nice and simple Tabs control for Blazor to use in our projects. If you have any comment please add it at the bottom of this post or use the Forum.
The post Tabs control for Blazor appeared first on PureSourceCode.
from WordPress https://www.puresourcecode.com/dotnet/blazor/tabs-control-for-blazor/
Write a reusable Blazor component
In this blog I have already talked about creating components but now I want to start from the beginning and explain how to write a reusable Blazor component from scratch. This is the first part of a Blazor article series to tell how to create a reusable Blazor component. So, we can use them in our Blazor application independently of the hosting model (Web Assembly or Server-side). If you google a bit, you can find a lot of example like that but I canāt find one example that explain exactly how the interaction works. Here, step by step what I understood.
Then, for more documentation, example and components about Blazor, here same links in this blog:
Getting Started With C# And Blazor
Setting Up A Blazor WebAssembly Application
Working With Blazorās Component Model
Secure Blazor WebAssembly With IdentityServer4
Blazor Using HttpClient With Authentication
InputSelect component for enumerations in Blazor
Use LocalStorage with Blazor WebAssembly
Modal Dialog component for Blazor
Create Tooltip component for Blazor
Consume ASP.NET Core Razor components from Razor class libraries | Microsoft Docs
Also, you can download the source code of this post from GitHub.
So, there result of this post is a simple button. When you click the button, Blazor calls the code in a javascript file and runs it. The result is passed to the C# code and then as result of the component.
Start!
First, I have to create a new Blazor project. For that, Create a new project and search for Blazor. Then, select Blazor WebAssembly App.
Visual Studio 2019 ā Create a new project
Then, you have to select the name of the project and its location. The name of my project is PSCBlazor and you can find it on GitHub.
Configure a new project
Select as Target Framework .NET 5. Then, Create.
Addition Information
Now, we have the main project. But to write a reusable Blazor component, we have to create another project for it. Following the same procedure, create a new project but this time select Razor Class Library.
Create a Razor Class Library
Then, follow the instruction. The name of my project is PSCBlazor.SimpleComponent.
If you donāt want to use Visual Studio, you can run from the Command Line
dotnet new razorclasslib
By default, the created project contains several elements:
A predefinedĀ āComponent1āĀ that is a basic component displaying some styled text in Component1.razor.
AĀ ExampleJsInteropĀ class that demonstrate how to call a basic JS function defined in its own js file inĀ ExampleJsInterop.cs.
The static resources (like png, css and js files) in the āwwwrootā folder: āĀ background.png āĀ exampleJsInterop.js āĀ styles.css
The solution for the custom component
Separate the code from the razor code
Behind the scenes, when you write a razor page, an actual C# class is generated and hopefully the class is partial. It means that it is easy to separate the behavioral code of your component from the html view code.
Single mixed file Component1.razor:
<div class="my-component"> This Blazor component is defined in the <strong>PSCBlazor.SimpleComponent</strong> package. </div> @code { }
Sometimes it is nice to separate the view from the code. In Visual Studio is pretty simple. Create a new Class with the full name of the view file plus cs. For example, if the view is Component1.razor the new file should be Component.razor.cs and automatically Visual Studio understands that this file is part of the view.
Split view and code
Then, a little change in the code because the new class must be a partial class. For example:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PSCBlazor.SimpleComponent { public partial class Component1 { } }
Interop between Blazor and JavaScript
Now, I write a reusable component for Blazor and Iām going to modify the component to be able to exchange some data between the component itself and the parent. For that, I have to use a JS function through the generatedĀ ExampleJsInteropĀ to prompt the user for a text input.
The component will be used this way with TextValue being a property used in the binding:
<Component1 ParentName=āSome text I want to transmit from the parent to the child componentā @bind-Text=āTextValueā> </Component1>
Define the parameters
We need to define a property ParentName to transmit some data from the parent to the child component:
[Parameter] public string ParentName { get; set; }
The Parameter attribute tells that the C# property can be used as component parameter.
Now, I need to define a parameter to be able to transmit data to the child component, but we also want to get data from the component using a @bind property.
To make it possible, I have to define a parameter like the previous one named in our case Text.
[Parameter] public string Text { get; set; }
Define a EventCallback parameter to be able to notify the binding engine that the value has changed.Ā As a convention, the name of the event callback property must be named accordingly to the property you want to bind. In our case it must be named TextChanged.
[Parameter] public EventCallback<string> TextChanged { get; set; }
The name of the event callback can be named differently but in that case it is required to specify it when binding a value using
@bind-{Property}:event=āNameOfPropertyChangedā
It means that the two notation are equivalent when binding a value:
<Child @bind-MyProperty="Text" /> <Child @bind-MyProperty="Text" @bind-MyProperty:event="TextChanged" />
Once the properties are defined, the component will have to invoke the event callback when the property value is changing.
await TextChanged.InvokeAsync(valueOfUserTextInputFromModalDialog);
Inject the appropriate services
To use the Java Script interop and the ExampleJsInterop example class we have to use an injected instance of IJSRuntime. We can do it with a dedicated attribute Inject in the component C# file.
Implement the behavior
Now, I have all we need to implement the behavior by adding a button with a click handler that is going to call the JS function through the ExampleJsInterop.Prompt method. Once we got the result we just need to forward to the TextChanged event call back and to update our Text property value.
So, in the razor file I created a bit of HTML, just to have a bit more fun.
<div class="my-component"> <div class="my-buttonkeeper"> <button class="my-button" @onclick="GetTextAsync">Click me</button> </div> </div> <br /> <text>Text (in the component) : @Text</text> <br />
Then, in the Component1.razor.css I added some CSS code
.my-component { border: 2px dashed red; padding: 1em; margin: 1em 0; background-image: url('background.png'); } .my-buttonkeeper { text-align: center; } .my-button { width: 150px; height: 150px; background-color: green; color: white; font-size: 20px; }
Why? Because I want to be sure the main application adds the CSS from this component but also the javascript we need. Iāll explain that in a second.
Then, it is the moment of the CS file:
private async Task GetTextAsync() { // Call JS interop. var text = await new ExampleJsInterop(JsRuntime).Prompt("Enter some text:"); // Trigger the changed event. await TextChanged.InvokeAsync(text); // Set the property value. Text = text; }
InsideĀ wwwrootĀ directory we have ready to useĀ exampleJsInterop.jsĀ file which was created by Visual Studio or CLI. The code is like that
// This is a JavaScript module that is loaded on demand. It can export any number of // functions, and may import other JavaScript modules if required. export function showPrompt(message) { return prompt(message, 'Type anything here'); }
This is a simple javascript function. This rings a bell to me, it is like in React. Now, the magic is happening in the ExampleJsInterop.cs
using Microsoft.JSInterop; using System; using System.Threading.Tasks; namespace PSCBlazor.SimpleComponent { // This class provides an example of how JavaScript functionality can be wrapped // in a .NET class for easy consumption. The associated JavaScript module is // loaded on demand when first needed. // // This class can be registered as scoped DI service and then injected into Blazor // components for use. public class ExampleJsInterop : IAsyncDisposable { private readonly Lazy<Task<IJSObjectReference>> moduleTask; public ExampleJsInterop(IJSRuntime jsRuntime) { moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>( "import", "./_content/PSCBlazor.SimpleComponent/exampleJsInterop.js").AsTask()); } public async ValueTask<string> Prompt(string message) { var module = await moduleTask.Value; return await module.InvokeAsync<string>("showPrompt", message); } public async ValueTask DisposeAsync() { if (moduleTask.IsValueCreated) { var module = await moduleTask.Value; await module.DisposeAsync(); } } } }
So, between the lines 24 and 28 there is a call via IJSObjectReference to the javascript function in the file under the wwwroot. You can see that in line 21 where there is an import of the javascript file.
Run the demo project
So, almost finish to write a reusable Blazor component with interop with javascript. First, I have to add the component as dependency in the project. In Solution Explorer, right click on Dependecies in the PSCBlazor and click on Add project references⦠Then, select the component.
Reference manager
Now, open _Imports.razor and add the reference to this component to add this line
@using PSCBlazor.SimpleComponent
Then, open Index.razor and add this code
<Component1 ParentName="This is a test" @bind-Text="_text"></Component1> The text from the component is: @_text @code { private string _text = ""; }
Also, we want to add the CSS and the javascript for the magic. Depending on the hosting model, it is required to add the reference to the CSS and javascript in specific index files in the application project:
wwwroot/index.htmlĀ for the Web Assembly hosting model.
and
Pages/_Host.cshtmlĀ for the Server-side hosting model.
So, open the index.html under wwwroot and add those lines (I deleted a lot of lines for the purpose of showing what you have to add):
<head> <link href="_content/PSCBlazor.SimpleComponent/styles.css" rel="stylesheet" /> </head> <body> <script src="_framework/blazor.webassembly.js"></script> <script src="_content/PSCBlazor.SimpleComponent/exampleJsInterop.js" /> </body>
Basically, in the head I have to add the reference to the CSS from the component. Similarly, I have to do the same to add the javascript.
Compile and run. If everything is ok, you have the same result as I show at the top of this post.
The post Write a reusable Blazor component appeared first on PureSourceCode.
from WordPress https://www.puresourcecode.com/dotnet/blazor/write-a-reusable-blazor-component/
InputSelect component for enumerations in Blazor
In this new post about Blazor, Iām going to give you the code for InputSelect component for enumerations in Blazor. In the last few weeks Iām starting to talk about Blazor and here you have the other posts:
Getting Started With C# And Blazor
Setting Up A Blazor WebAssembly Application
Working With Blazorās Component Model
Secure Blazor WebAssembly With IdentityServer4
Blazor Using HttpClient With Authentication
Itās common to use a dropdown list to select a value from an enumeration. In ASP.NET Core MVC you can useĀ Html.GetEnumSelectListĀ to create the items for an enumeration. This is very convenient and very productive. However, this helper doesnāt exist in Blazor. In this post, weāll create something even easier to use.
The componentĀ InputSelectĀ allows binding a property of type Enum. However, you need to provide all options manually which is error-prone and not very productive:
<EditForm Model="model"> <InputSelect @bind-Value="model.Season"> <option>Spring</option> <option>Summer</option> <option>Autumn</option> <option>Winter</option> </InputSelect> </EditForm> @code { Model model = new Model(); class Model { public Season Season { get; set; } } enum Season { Spring, Summer, Autumn, Winter } }
You can make this code more generic by iterating onĀ Enum.GetValues:
<EditForm Model="model"> <InputSelect @bind-Value="model.Season"> @foreach (var value in Enum.GetValues(typeof(Season))) { <option>@value</option> } </InputSelect> </EditForm>
This way you can copy/paste the code for any enumeration you want to bind to a select. However, the display text is not customizable, so not very use friendly. It is also not localized. As always in Blazor, the solution is to create a component! Components allow encapsulating reusable behaviors. Then, you can use them in your other components and avoid duplicating code.
InputSelectEnum Blazor component
To create this component, I checked how theĀ InputSelectĀ component is madeĀ on GitHub. The code is very simple. It contains 2 methods:Ā BuildRenderTreeĀ andĀ TryParseValueFromString. Weāll change the first one to populate theĀ optionĀ elements when creating the tree instead of using the templateĀ ChildContent. TheĀ TryParseValueFromStringĀ method converts the string value from theĀ selectĀ element to a valid enumeration value. Weāll adapt this method to support nullable types.
A few points to note in the implementation:
This component supports nullable types which is not the case of theĀ InputSelectĀ component.
This component read theĀ [Display]Ā attribute to create the option display names. If no attribute is defined, it decamelizes the enumeration member name. This attribute allows localizing the application.
In previous posts, we have created components using the razor syntax. In this case, it is easier to create the component in C# code only. You can add the code in the āSharedā folder, so the component is accessible in all the views. Iāve added a few comments to explain the code. But donāt worry, thereās nothing complicated in this component.
using System; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Reflection; using Humanizer; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Rendering; // Inherit from InputBase so the hard work is already implemented
// Note that adding a constraint on TEnum (where T : Enum) doesn't work when used in the view, Razor raises an error at build time. Also, this would prevent using nullable types... public sealed class InputSelectEnum<TEnum> : InputBase<TEnum> { // Generate html when the component is rendered. protected override void BuildRenderTree(RenderTreeBuilder builder) { builder.OpenElement(0, "select"); builder.AddMultipleAttributes(1, AdditionalAttributes); builder.AddAttribute(2, "class", CssClass); builder.AddAttribute(3, "value", BindConverter.FormatValue(CurrentValueAsString)); builder.AddAttribute(4, "onchange", EventCallback.Factory.CreateBinder<string>(this, value => CurrentValueAsString = value, CurrentValueAsString, null)); // Add an option element per enum value var enumType = GetEnumType(); foreach (TEnum value in Enum.GetValues(enumType)) { builder.OpenElement(5, "option"); builder.AddAttribute(6, "value", value.ToString()); builder.AddContent(7, GetDisplayName(value)); builder.CloseElement(); } builder.CloseElement(); // close the select element } protected override bool TryParseValueFromString(string value, out TEnum result, out string validationErrorMessage) { // Let's Blazor convert the value for us
if (BindConverter.TryConvertTo(value, CultureInfo.CurrentCulture, out TEnum parsedValue)) { result = parsedValue; validationErrorMessage = null; return true; } // Map null/empty value to null if the bound object is nullable if (string.IsNullOrEmpty(value)) { var nullableType = Nullable.GetUnderlyingType(typeof(TEnum)); if (nullableType != null) { result = default; validationErrorMessage = null; return true; } } // The value is invalid => set the error message result = default; validationErrorMessage = $"The {FieldIdentifier.FieldName} field is not valid."; return false; } // Get the display text for an enum value: // - Use the DisplayAttribute if set on the enum member, so this support localization // - Fallback on Humanizer to decamelize the enum member name private string GetDisplayName(TEnum value) { // Read the Display attribute name var member = value.GetType().GetMember(value.ToString())[0]; var displayAttribute = member.GetCustomAttribute<DisplayAttribute>(); if (displayAttribute != null) return displayAttribute.GetName(); // Require the NuGet package Humanizer.Core // <PackageReference Include = "Humanizer.Core" Version = "2.8.26" /> return value.ToString().Humanize(); } // Get the actual enum type. It unwrap Nullable<T> if needed // MyEnum => MyEnum // MyEnum? => MyEnum private Type GetEnumType() { var nullableType = Nullable.GetUnderlyingType(typeof(TEnum)); if (nullableType != null) return nullableType; return typeof(TEnum); } }
You can now use this component in another Blazor component:
<EditForm Model="model"> <div> @* The type of the enum (TEnum) is detected by the type of the bound property which is just awesome! *@ <InputSelectEnum @bind-Value="model.Season" /> <span>Selected value: @model.Season</span> </div> </EditForm> @code { Model model = new Model(); class Model { public Season Season { get; set; } } enum Season { [Display(Name = "Spring", ResourceType = typeof(Resources))] Spring, [Display(Name = "Summer", ResourceType = typeof(Resources))] Summer, [Display(Name = "Autumn", ResourceType = typeof(Resources))] Autumn, [Display(Name = "Winter", ResourceType = typeof(Resources))] Winter, } }
The post InputSelect component for enumerations in Blazor appeared first on PureSourceCode.
from WordPress https://www.puresourcecode.com/dotnet/blazor/inputselect-component-for-enumerations-in-blazor/