ASP.NET Core 5.0 : MVC, Razor Pages, Web API, EF Core, Blazor, Design Patterns, and more. Private online coaching for software developers. Click here for more details.

Separate UI and Code in Blazor

Blazor apps consist of one or more components. Components reside in .razor files and consist of UI markup and C# code. When you create a new Blazor server or WebAssembly project it stores component UI and code in a single file. However, at times this single file approach might not be adequate. Luckily, you can separate your UI markup and C# code easily. This article shows how.

Single file

Firstly, let's see how the UI markup and C# code is stored under the single file approach.

Begin by creating a new Blazor server project using Visual Studio. The following figure shows the newly created project in Solution Explorer. 

Then open the Counter.razor component from the Pages folder to reveal this markup and code:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" 
        @onclick="IncrementCount">
        Click me
</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

As you can see the component UI markup is placed after @page directive. And component's C# code is placed inside the @code block.

That means UI markup and C# code are housed in a single file. This arrangement works well when your components are simple and don't contain huge chunks of markup and code. Single file approach is also good if you want keep minimal number of project files. However, if you are developing complex components you might want to separate UI markup and C# code in separate files.

There are two ways to accomplish that task - Partial class approach and Base class approach.

Let's see both of them in action.

Partial class

In this approach you create a partial class matching the name of the component. For example, the Counter component exists in Component.razor file. So, you need to create a partial class called Counter. Then you need to write all the C# code into the partial class. The UI markup will remain in the Counter.razor file.

Here, we will create a new component and copy the code from Counter component into it. This way we can test all the approaches in a single project.

Add a new Razor Component named Counter1.razor using Add New Item dialog.

Then add a new C# class file called Counter1.razor.cs.

The name of the class file can be anything but if you stick to this convention Visual Studio will show it as a nested file of Counter1.razor.

Now copy the UI code from Counter.razor into Counter1.razor file.

@page "/counter1"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary"
        @onclick="IncrementCount">
    Click me
</button>

Note that after coping the code we change the @page directive to /counter1 to avoid duplicate routes.

Then copy everything from the @code block of Counter.razor to Counter1.razor.cs. This is shown below:

public partial class Counter1
{
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Notice that Counter1 class is marked to be a partial class.

We just created Counter1 component that separates its UI and C# code into different files.

Base class

Let's see the base class approach. This approaches also involves a .razor file and a corresponding .cs file but rather than creating a partial class we resort to inheritance.

Add another Razor Component called Counter2.razor. Also add a new C# class file called Counter2.razor.cs.

Now open the Counter2.razor.cs file and write the following class definition into it.

public class Counter2Base : ComponentBase
{
    protected int currentCount = 0;

    protected void IncrementCount()
    {
        currentCount++;
    }
}

Notice that the class name is Counter2Base and it inherits from ComponentBase class. This class name can be anything. But to avoid any ambiguity with the Counter2, we call it Counter2Base.

Also notice that the class members are changed from private to protected. This is required because we are going to use inheritance (rather than partial class) in this example.

Now modify the Counter2.razor file as shown below:

@page "/counter2"

@inherits Counter2Base

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary"
        @onclick="IncrementCount">
    Click me
</button>

As before we assign some different route to this component. Moreover, Counter2 component inherits from Counter2Base class. This is indicated using @inherits directive.

Now, let's see whether all the three components work as expected.

Open NavMenu.razor file and add two menu entries for the two additional components we created.

<li class="nav-item px-3">
    <NavLink class="nav-link" href="counter">
        <span class="oi oi-plus" aria-hidden="true">
        </span> Counter
    </NavLink>
</li>
<li class="nav-item px-3">
    <NavLink class="nav-link" href="counter1">
        <span class="oi oi-plus" aria-hidden="true">
        </span> Counter1
    </NavLink>
</li>
<li class="nav-item px-3">
    <NavLink class="nav-link" href="counter2">
        <span class="oi oi-plus" aria-hidden="true">
        </span> Counter2
    </NavLink>
</li>

Run the project and navigate to all the three "counter" components from the left side menu.

Click on the "Click me" button of each counter component and check whether it displays the correct value.

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant, trainer, author, yoga mentor, and meditation teacher. He has been programming, meditating, and teaching for 24+ years. He conducts instructor-led online training courses in ASP.NET family of technologies for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Facebook  Twitter  LinkedIn  YouTube

Posted On : 07 December 2020


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio Components


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.

  

Receive Weekly Updates