Features

Overview

Overview

The MultiRow control extends conventional grid layouts by using multiple rows to represent each data item.

Features

Settings

This view uses two rows per record. The layout is divided into three groups: order, customer, and shipper.

Description

The MultiRow control extends conventional grid layouts by using multiple rows to represent each data item.

The MultiRow control allows users to see and edit data in a tabular form, just like other conventional grids. But, MultiRow is different from these grids in a way that it allows you to bind each data item to multiple rows, creating form-like interfaces that can display a large number of columns with minimal horizontal scrolling.

The MultiRow control extends the FlexGrid control, so if you know how to use FlexGrid, you will be able to use MultiRow in no time. The main new property is LayoutDefinition, which takes an object that describes the layout of the grid rows and cells.

The MultiRow control is not a simple replacement for conventional grids; it is a specialized tool that fits some particular scenarios really well.

LayoutDefinition

The LayoutDefinition property specifies the layout of the cells in the grid. It contains a list of cell group objects. Each cell group specifies how many columns the group should span, and the cells that make up each group.

The image below illustrates how a cell group is interpreted and turned into a grid layout:

The group spans three grid columns. It contains six cells with different spans. When generating the layout, the grid fits as many cells as possible in each row, and wraps to the next row when the group span is reached. The last cell in each row is automatically expanded to fill Colspan of the group. The process is similar to wrapping of text to create a paragraph.

The same process is applied to every group in the LayoutDefinition object.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using MultiRowExplorer.Models;
using Microsoft.AspNetCore.Http;
using C1.Web.Mvc;
using C1.Web.Mvc.Serialization;

namespace MultiRowExplorer.Controllers
{
    public partial class MultiRowController : Controller
    {
        private readonly ControlOptions _options = new ControlOptions
        {
            Options = new OptionDictionary
            {
                {"Layout Definition",new OptionItem{Values = new List<string> {"Traditional", "Compact", "Detailed"},CurrentValue = "Compact"}}
            }
        };

        public ActionResult Index(IFormCollection collection)
        {
            _options.LoadPostData(collection);
            ViewBag.DemoOptions = _options;
            return View();
        }

        public ActionResult Index_Bind([C1JsonRequest] CollectionViewRequest<Orders.Order> requestData)
        {
            var model = Orders.GetOrders();
            return this.C1Json(CollectionViewHelper.Read(requestData, model));
        }
    }
}
@model IEnumerable<Orders.Order>
@{
    var cities = Orders.GetCities().ToValues();
    ControlOptions optionsModel = ViewBag.DemoOptions;
    ViewBag.DemoSettings = true;

    var layoutDefinition = optionsModel.Options["Layout Definition"].CurrentValue;
}

@if (layoutDefinition == "Traditional")
{
    <c1-multi-row id="ovMultiRowTraditional" class="multirow">
        <c1-items-source read-action-url="@Url.Action("Index_Bind")"></c1-items-source>
        <c1-multi-row-cell-group colspan="15">
            <c1-multi-row-cell binding="Id" header="ID" class="id" />
            <c1-multi-row-cell binding="Date" header="Ordered" />
            <c1-multi-row-cell binding="ShippedDate" header="Shipped" />
            <c1-multi-row-cell binding="Amount" header="Amount" format="c" class="amount" />
            <c1-multi-row-cell binding="Customer.Name" name="CustomerName" header="Customer" />
            <c1-multi-row-cell binding="Customer.Address" name="CustomerAddress" header="Address" />
            <c1-multi-row-cell binding="Customer.City" name="CustomerCity" header="City" show-drop-down="true">
                <c1-data-map display-member-path="Value" selected-value-path="Value">
                    <c1-items-source source-collection="cities" />
                </c1-data-map>
            </c1-multi-row-cell>
            <c1-multi-row-cell binding="Customer.State" name="CustomerState" header="State" />
            <c1-multi-row-cell binding="Customer.Zip" name="CustomerZip" header="Zip" />
            <c1-multi-row-cell binding="Customer.Email" name="CustomerEmail" header="Customer Email" class="email" />
            <c1-multi-row-cell binding="Customer.Phone" name="CustomerPhone" header="Customer Phone" />
            <c1-multi-row-cell binding="Shipper.Name" name="ShipperName" header="Shipper" />
            <c1-multi-row-cell binding="Shipper.Email" name="ShipperEmail" header="Shipper Email" class="email" />
            <c1-multi-row-cell binding="Shipper.Phone" name="ShipperPhone" header="Shipper Phone" />
            <c1-multi-row-cell binding="Shipper.Express" name="ShipperExpress" header="Express" />
        </c1-multi-row-cell-group>
    </c1-multi-row>
}

@if (layoutDefinition == "Compact")
{
    <c1-multi-row id="ovMultiRowCompact" class="multirow">
        <c1-items-source read-action-url="@Url.Action("Index_Bind")"></c1-items-source>
        <c1-multi-row-cell-group header="Order" colspan="2">
            <c1-multi-row-cell binding="Id" header="ID" width="150" class="id" />
            <c1-multi-row-cell binding="Date" header="Ordered" width="150" />
            <c1-multi-row-cell binding="Amount" header="Amount" format="c" class="amount" />
            <c1-multi-row-cell binding="ShippedDate" header="Shipped" />
        </c1-multi-row-cell-group>
        <c1-multi-row-cell-group header="Customer" colspan="3">
            <c1-multi-row-cell binding="Customer.Name" name="CustomerName" header="Customer" width="200" />
            <c1-multi-row-cell binding="Customer.Email" name="CustomerEmail" header="Customer Email" class="email" colspan="2" />
            <c1-multi-row-cell binding="Customer.Address" name="CustomerAddress" header="Address" />
            <c1-multi-row-cell binding="Customer.City" name="CustomerCity" header="City" show-drop-down="true">
                <c1-data-map display-member-path="Value" selected-value-path="Value">
                    <c1-items-source source-collection="cities" />
                </c1-data-map>
            </c1-multi-row-cell>
            <c1-multi-row-cell binding="Customer.State" name="CustomerState" header="State" />
        </c1-multi-row-cell-group>
        <c1-multi-row-cell-group header="Shipper" colspan="2">
            <c1-multi-row-cell binding="Shipper.Name" name="ShipperName" header="Shipper" colspan="2" />
            <c1-multi-row-cell binding="Shipper.Email" name="ShipperEmail" header="Shipper Email" class="email" width="200" />
            <c1-multi-row-cell binding="Shipper.Express" name="ShipperExpress" header="Express" width="100" />
        </c1-multi-row-cell-group>
    </c1-multi-row>
}

@if (layoutDefinition == "Detailed")
{
    <c1-multi-row id="ovMultiRowDetailed" class="multirow">
        <c1-items-source read-action-url="@Url.Action("Index_Bind")"></c1-items-source>
        <c1-multi-row-cell-group header="Order" colspan="2">
            <c1-multi-row-cell binding="Id" header="ID" class="id" colspan="2" />
            <c1-multi-row-cell binding="Amount" header="Amount" format="c" class="amount" colspan="2" />
            <c1-multi-row-cell binding="Date" header="Ordered" />
            <c1-multi-row-cell binding="ShippedDate" header="Shipped" />
        </c1-multi-row-cell-group>
        <c1-multi-row-cell-group header="Customer" colspan="3">
            <c1-multi-row-cell binding="Customer.Name" name="CustomerName" header="Customer" />
            <c1-multi-row-cell binding="Customer.Email" name="CustomerEmail" header="Customer Email" class="email" colspan="2" />
            <c1-multi-row-cell binding="Customer.Address" name="CustomerAddress" header="Address" colspan="2" />
            <c1-multi-row-cell binding="Customer.Phone" name="CustomerPhone" header="Customer Phone" />
            <c1-multi-row-cell binding="Customer.City" name="CustomerCity" header="City" show-drop-down="true">
                <c1-data-map display-member-path="Value" selected-value-path="Value">
                    <c1-items-source source-collection="cities" />
                </c1-data-map>
            </c1-multi-row-cell>
            <c1-multi-row-cell binding="Customer.State" name="CustomerState" header="State" />
            <c1-multi-row-cell binding="Customer.Zip" name="CustomerZip" header="Zip" />
        </c1-multi-row-cell-group>
        <c1-multi-row-cell-group header="Shipper">
            <c1-multi-row-cell binding="Shipper.Name" name="ShipperName" header="Shipper" width="*" />
            <c1-multi-row-cell binding="Shipper.Email" name="ShipperEmail" header="Shipper Email" class="email" />
            <c1-multi-row-cell binding="Shipper.Express" name="ShipperExpress" header="Express" />
        </c1-multi-row-cell-group>
    </c1-multi-row>
}

@section Settings{
    @Html.Partial("_OptionsMenu", optionsModel)
    @if (layoutDefinition == "Traditional")
    {
        <p>Traditional grid view, with one row per record.The user must scroll horizontally to see the whole record.</p>
    }
    @if (layoutDefinition == "Compact")
    {
        <p>This view uses two rows per record. The layout is divided into three groups: order, customer, and shipper.</p>
    }
    @if (layoutDefinition == "Detailed")
    {
        <p>This view uses three rows per record. The layout is divided into three groups: order, customer, and shipper.</p>
    }
}

@section Summary{
    <p>The MultiRow control extends conventional grid layouts by using multiple rows to represent each data item.</p>
}

@section Description{
    <p>
        The <b>MultiRow</b> control extends conventional grid layouts by using multiple rows to represent each data item.
    </p><p>
        The <b>MultiRow</b> control allows users to see and edit data in a tabular form, just like other conventional grids.
        But, <b>MultiRow</b> is different from these grids in a way that it allows you to bind each data item to multiple rows,
        creating form-like interfaces that can display a large number of columns with minimal horizontal scrolling.
    </p><p>
        The <b>MultiRow</b> control extends the <b>FlexGrid</b> control, so if you know how to use <b>FlexGrid</b>, you will be able to use <b>MultiRow</b> in no time.
        The main new property is <b>LayoutDefinition</b>, which takes an object that describes the layout of the grid rows and cells.
    </p><p>
        The <b>MultiRow</b> control is not a simple replacement for conventional grids; it is a specialized tool that fits some particular scenarios really well.
    </p>
    <h3 class="semi-bold">LayoutDefinition</h3>
    <p>
        The <b>LayoutDefinition</b> property specifies the layout of the cells in the grid.
        It contains a list of cell group objects. Each cell group specifies how many columns the group should span, and the cells that make up each group.
    </p><p>
        The image below illustrates how a cell group is interpreted and turned into a grid layout:
        <img src="~/Content/images/cellGroup.png" />
    </p><p>
        The group spans three grid columns. It contains six cells with different spans.
        When generating the layout, the grid fits as many cells as possible in each row, and wraps to the next row when the group span is reached.
        The last cell in each row is automatically expanded to fill <b>Colspan</b> of the group.
        The process is similar to wrapping of text to create a paragraph.
    </p><p>
        The same process is applied to every group in the <b>LayoutDefinition</b> object.
    </p>
}