Telerik blogs
blazort_870x220

So what can you do with a TreeView? Well, by combining the TreeView and Window components in Telerik UI for Blazor, you can let the user find the data they want and control how much data you inflict on them.

The TreeView in Telerik UI for Blazor allows you to decide what happens when a user interacts with the nodes in the TreeView. That lets you deliver a UI that gives the user what they want, when they want it.

While the Telerik TreeView for Blazor makes it easy to load the data you want, that still leaves the question of, “What would I do with a treeview once I load it?” One option is to use the treeview’s hierarchical display to allow the user to control what makes up a page’s UI.

Managing the Display

For example, let’s say that you want to present a list of customer types (or product categories) where each type has multiple customers (for product categories, each category would have multiple individual products). Where the number of top-level items (types of categories) and the number of items for each node level isn’t overwhelming, a treeview display lets the user drill down to the data they want, guided by the information displayed in the treeview’s nodes. That information is typically terse: the customer type name or the product category name at the top level, the customer or product name at the next level.

A treeview doesn’t have to be limited to just two levels. You can add additional levels as necessary so that, for example, a user could expand a particular customer to display that customer’s addresses or sales orders (or expand a product to display its purchase history or the various warehouses it’s held in).

Again, however, the information in the treeview is typically terse — just enough information to let the user navigate to what they want. But once the user finds the node they want, the user will typically want more detailed information about the selected item (more information about the selected customer/address or product/warehouse, for example). Because each node is associated with a Customer or Product object, you have that information available to display. All you have to do is give the user a way to select the detailed display (though, having said that, the Telerik TreeView does let you put as much information as you want in each node if you’re comfortable with more wordy nodes).

In general, treeviews support this kind of interaction by separating the ability to expand a node in the treeview (click on the arrow to the node’s left) from the ability to display the node’s data (click on the node itself). By providing templates for each node, the Telerik TreeView allows you to go beyond that to decide what interaction the nodes at each level will support.

Defining the TreeView

For example, let’s start with a TreeView that displays a collection of customers with their related addresses. The markup for that TreeView might look like this:

<TelerikTreeView Data="@custs">
    <TreeViewBindings>
        <TreeViewBinding TextField="FullName" ItemsField="Addresses">
            </ItemTemplate>
        </TreeViewBinding>
        <TreeViewBinding Level="1" TextField="Type">
        </TreeViewBinding>
    </TreeViewBindings>
</TelerikTreeView>

This markup ties the TreeView to a list of customer objects (held in a field I’ve called custs), each of which has an Addresses collection holding the customer’s Address objects. The markup displays each customer’s FullName property and each address’s Type property (the Type property flags what kind of address is being displayed: shipping, billing, etc.).

To customize the node’s appearance and behavior, I can add an ItemTemplate inside the TreeViewBinding element. Here’s the customer node with an ItemTemplate (because I’m using a template to control the node’s display, I no longer need the TreeViewBinding’s FullName attribute):

<TreeViewBinding ItemsField="Addresses">
   <ItemTemplate>
    …content…
   </ItemTemplate>
</TreeViewBinding>

I could use any number of UI items inside the template to give the user something to interact with. What I decided on was an anchor element with its onclick method set to call a method in the code section of my component (I called the method SetCurrentCustomer). Inside an ItemTemplate I have access to the node’s context field which holds the object attached to the current node (in this case, that’s a Customer object). I’ll need that Customer object to display the customer’s detailed information when the user clicks on my anchor element. In my onclick event, I pass the context object to my SetCurrentCustomer method.

After making all of those changes, my customer node looks like this:

<TreeViewBinding ItemsField="Addresses">
   <ItemTemplate>
      <a @onclick="() => SetCurrentCustomer((context as Customer))">@((context as Customer).FullName)</a>
      </ItemTemplate>
</TreeViewBinding>

Effectively, by selecting a node, the user has identified the “current customer” whose detailed data the user wants to see. I’ll provide that display later — for now, in my SetCurrentCustomer method, I’ll just catch the node’s Customer object and stuff it into a property:

Customer CurrentCustomer {get; set;}
private void SetCurrentCustomer(Customer cust)
{
   CurrentCustomer = cust;
}

I’ll do a similar thing with the second level of my treeview (the address nodes for each customer). The markup for that second level would look like this:

<TreeViewBinding Level="1">
   <ItemTemplate>
      <a @onclick="() => SetCurrentAddress((context as Address))">@((context as Address).Type)</a>
   </ItemTemplate>
</TreeViewBinding>

And here’s the related code:

Address CurrentAddress {get; set;}
private void SetCurrentAddress(Address addr)
{
        CurrentAddress = addr;
}

Managing the Page Display

Of course, I now need to display the detailed data for my Customer and Address objects. The easiest way to do that is to use Telerik’s Window component to hold the markup for each set of data. I’ll use two Boolean fields to control when each window is visible (visibleCustomer for the window with customer information; visibleAddress for the window with address information). The windows simply display the data of whatever object is in my CurrentCustomer and CurrentAddress properties.

Here’s the markup for those two windows with the fields that manage their visibility:

<TelerikWindow Visible="@visibleCustomer" Centered="false" Top="100px" Left="500px">
    <WindowTitle>
        Customer: @currentCustomer.CustId
    </WindowTitle>
    <WindowContent>
        Name: @currentCustomer.FullName
        …more data…
    </WindowContent>
</TelerikWindow>
<TelerikWindow Visible="@visibleAddress" Centered="false" Top="200px" Left="500px">
    <WindowTitle>
        Address: @currentAddress.Type
    </WindowTitle>
    <WindowContent>
        Name: @currentAddress.City
        …more data….
    </WindowContent>
</TelerikWindow>
@code {
    private bool visibleAddress;
    private bool visibleCustomer;

Now it’s just a matter of managing the display of the two windows. When a user clicks on a customer node, I want to store the Customer object to support the data displayed in the customer window data. I also want to hide any existing windows with address information so that I’m not displaying address information for one customer along with customer information for a different customer. And, of course, I want to display the customer window.

I can just put the code to handle that in the CurrentCustomer property that I update when the user clicks on a Customer node:

private CustomerDto currentCustomer;
private CustomerDto CurrentCustomer
{
   get
   {
      return currentCustomer;
   }
   set
   {
      if (currentCustomer != value)
      {
         currentCustomer = value;
         visibleAddress = false;
         visibleCustomer = true;
      }
   }
}

When the user clicks on an address node, the code is roughly similar. For example, I still want to store the Address object to support the display in the address window. With the Address object, however, I also want to update the current customer property to show the customer for that address (each Address object has a Customer property that points back to the address’s “owner”). To do that, all I have to do is set my CurrentCustomer property, which takes care of handling the display of the customer window. Finally, I need to display the address window. That code looks like this:

private Address currentAddress;
private Address CurrentAddress
{
   get
   {
      return currentAddress;
   }
   set
   {
      if (currentAddress != value)
      {
         currentAddress = value;
         currentCustomer = currentAddress.Customer;
         visibleAddress = true;
      }
   }
}

So, by leveraging the Telerik controls, I’ve got an interactive display that allows the user to drill down to the data they want while choosing between the summary data in the node’s template and the more extensive information in the related window. Not bad for a morning’s work.

Try it Today

To learn more about Telerik UI for Blazor components and what they can do, check out the Blazor demo page or download a trial to start developing right away.

Start Trial


Peter Vogel
About the Author

Peter Vogel

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter also writes courses and teaches for Learning Tree International.

Related Posts

Comments

Comments are disabled in preview mode.