Segment control for Blazor

blazor segmented control

In this new post, I’m going to explain how to create a segmentcontrolforBlazor Web Assembly andBlazor Server. First of all, what is a segment control? A segmented control is a horizontal control made with multiple segments. Generally, we use segmented controls whenever we want to show a group of controls into separate sections. Born iniOS, a segment control looks like the following image:

iOS Segmented Control in Swift Sample Example

The full source code of this Blazor component is available onGitHub.

If you are looking for more examples of components, here some more links:

A new control

First, I have to create a new project for a new control as I didpreviously for other components. So, create a new project searching forRazor and selectRazor Class Library.

Create a new project with Visual Studio 2022 - Segment control for Blazor
Create a new project with Visual Studio 2022

Now, the segment component has 2Razor pages:

  • the segment container
  • the definition of a segment

So, start with the implementation.

Definition of a segment

First thing first. This is a simple page and its name isSegment.razor. In this page I check if there is aParent for it. If it is not a parent, I raise an error because a segment can’t exist without a segment container. As aParameter the component receives the content for this segment in theRenderFragment ChildContent. For each segment, I have 2 more parameters:

  • Text is the label you want to show to the user
  • Value is the real value you want to use

Then, theOnInitialized() checks if there is a parent and add this segment to the list present in the segment container. If this segment is the active one, the component shows the content.

So, all of this in this code for theSegment.razor is the following

@if (Parent.ActivePage == this){    @ChildContent}@code {    [CascadingParameter]    private Segments Parent { get; set; }    [Parameter]    public RenderFragment ChildContent { get; set; }    [Parameter]    public string Text { get; set; }    [Parameter]    public string Value { get; set; }    protected override void OnInitialized()    {        if (Parent == null)            throw new ArgumentNullException(nameof(Parent),                    "Segment must exist within a Segments container");        base.OnInitialized();        Parent.AddPage(this);    }}

Segment control

Now, the important part. So, I’m going to split in 2 parts this page: the pseudo-HTML with CSS and the code to better understand how it is working. This code is responsible to display the segment in the page.

Segment page

Then, the first part of theRazor page is the following:

<CascadingValue Value="this">    <div class="segment-control">        <ul class="segments">            @foreach (Segment tabPage in Pages)            {                <li class="@GetButtonClass(tabPage)"                    @onclick=@( () => ActivatePage(tabPage) )>                    @tabPage.Text                </li>            }        </ul>    </div>    @ChildContent</CascadingValue>

and the code part is this one

@code {    [Parameter]    public RenderFragment ChildContent { get; set; }        [Parameter]    public EventCallback<Segment> OnSegmentChanged { get; set; }    public Segment ActivePage { get; set; }    List<Segment> Pages = new List<Segment>();    internal void AddPage(Segment tabPage)    {        Pages.Add(tabPage);        if (Pages.Count == 1)            ActivePage = tabPage;        StateHasChanged();    }    string GetButtonClass(Segment page)    {        return page == ActivePage ? "selected" : "";    }    async Task ActivatePage(Segment page)    {        ActivePage = page;        await OnSegmentChanged.InvokeAsync(page);    }}

Cascading values and parameters are a way to pass a value from a component to all of its descendants without having to use traditional component parameters.

Blazor comes with a special component called CascadingValue. This component allows whatever value is passed to it to be cascaded down its component tree to all of its descendants. The descendant components can then choose to collect the value by declaring a property of the same type, decorated with the [CascadingParameter] attribute.

So, every new segment is added in the listPages. When a user click on a segment, the functionActivatePage changes theActivePage and the eventOnSegmentChanged is raised. With that in the page where you use the component, you are able to receive the event and run the code you want.

HTML and CSS structure

Now, you can see the segment container has adiv with classsegment-control. In it aul with classsegments. When ali is active, the class isselected. This is the CSS for the segment control in blue.

.segment-control {    padding: 2px;    width: 100%;    border: 1px solid #003250;    border-radius: 3px;}.segments {    display: -webkit-box;    -webkit-box-orient: horizontal;    -webkit-box-pack: justify;    -webkit-box-sizing: border-box;    padding-left: 0px;    margin-bottom: 0px;}.segments ul {    margin-top: 0px;    margin-bottom: 0px;}    .segments > li {        cursor: pointer;        margin: 2px;        display: block;        text-align: center;        background-color: #ffffff;        border-color: #003250;        border-radius: 3px;        color: #003250;        font-size: 12px;        padding: 2px;        -webkit-box-flex: 1;        -webkit-border-top-left-radius: 3px;        -webkit-border-bottom-left-radius: 3px;        -webkit-border-top-right-radius: 3px;        -webkit-border-bottom-right-radius: 3px;    }        .segments > li.selected {            background-color: #003250;            color: #fff;        }

So, out of the box, the segment component has 4 themes that you can use or write your custom theme.

How to use it

First, add the NuGet package in your project. The name of the package isPSC.Blazor.Components.Segments and the only dependency it has isMicrosoft.AspNetCore.Components.Web (>= 5.0.10).

After that, in yourwwwroot\index.html or in thehosts 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.Segments/themes/{theme-name}.css" rel="stylesheet" />

Out of the box, there are 4 themes (see below the images):

  • Blue (theme name: blue)
  • Green (theme name: green)
  • Red (theme name: red)
  • Light color (theme name: lightcolors)

Then, in your_Imports.razor add this

@using PSC.Blazor.Components.Segments

Now, you are ready to use your segment control.

Example

As a user, I want to select a country from a list of countries. When I click on one of them, other data has to change accordingly.

So, in a page add the following code:

<Segments OnSegmentChanged="OnSegmentChanged">    <Segment Text="Global" Value="global"></Segment>    <Segment Text="Australia" Value="australia"></Segment>    <Segment Text="Brazil" Value="brazil"></Segment>    <Segment Text="Canada" Value="canada"></Segment>    <Segment Text="France" Value="france"></Segment>    <Segment Text="Germany" Value="germany"></Segment>    <Segment Text="Italy" Value="italy"></Segment>    <Segment Text="Spain" Value="spain"></Segment>    <Segment Text="UK" Value="uk"></Segment></Segments>

EachSegment has 2 properties:

  • Text: the label you want to show to the user
  • Value: the real value you want to use

So, theSegments has the propertyOnSegmentChanged that it is invoked every time a user click on a segment. So, define the function in your page the segment has to invoke like that

public async Task OnSegmentChanged(Segment segment){    // code to run}

Themes

Now, there are 4 themes embedded in the segment control.

Blazor Segmentation example blue - Themes - Segment control for Blazor
Blazor Segmentation example blue
Blazor Segmentation example green - Themes - Segment control for Blazor
Blazor Segmentation example green
Blazor Segmentation example red - Themes - Segment control for Blazor
Blazor Segmentation example red
Blazor Segmentation example light colors - Themes - Segment control for Blazor
Blazor Segmentation example light colors

Wrap up

So, now we have a segment control for our Blazor applications. If you have any questions or comments, leave you message at the bottom of this post or use theForum.

Related posts

Leave a ReplyCancel reply

This site uses Akismet to reduce spam.Learn how your comment data is processed.