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 format, just like other conventional grids. However, 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 cells in a 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:

Here, 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 C1.Web.Mvc.Fluent;
using C1.Web.Mvc.Grid;
using C1.Web.Mvc.MultiRow;
using C1.Web.Mvc.MultiRow.Fluent;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MultiRowExplorer.Models
{
    public class LayoutDefinitionsBuilders
    {
        public static Action<ListItemFactory<CellGroup, CellGroupBuilder>> OneLine
        {
            get
            {
                return ld =>
                {
                    ld.Add().Colspan(15).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Id").Header("ID").CssClass("id"))
                            .Add(cell => cell.Binding("Date").Header("Ordered"))
                            .Add(cell => cell.Binding("ShippedDate").Header("Shipped"))
                            .Add(cell => cell.Binding("Amount").Header("Amount").Format("c").CssClass("amount"))
                            .Add(cell => cell.Binding("Customer.Name").Name("CustomerName").Header("Customer"))
                            .Add(cell => cell.Binding("Customer.Address").Name("CustomerAddress").Header("Address"))
                            .Add(cell => cell.Binding("Customer.City").Name("CustomerCity").Header("City")
                                .DataMap(dm => { dm.DisplayMemberPath("Value").SelectedValuePath("Value").Bind(Orders.GetCities().ToValues()); }))
                            .Add(cell => cell.Binding("Customer.State").Name("CustomerState").Header("State"))
                            .Add(cell => cell.Binding("Customer.Zip").Name("CustomerZip").Header("Zip"))
                            .Add(cell => cell.Binding("Customer.Email").Name("CustomerEmail").Header("Customer Email").CssClass("email"))
                            .Add(cell => cell.Binding("Customer.Phone").Name("Customerphone").Header("Customer Phone"))
                            .Add(cell => cell.Binding("Shipper.Name").Name("ShipperName").Header("Shipper"))
                            .Add(cell => cell.Binding("Shipper.Email").Name("ShipperEmail").Header("Shipper Email").CssClass("email"))
                            .Add(cell => cell.Binding("Shipper.Phone").Name("ShipperPhone").Header("Shipper Phone"))
                            .Add(cell => cell.Binding("Shipper.Express").Name("ShipperExpress").Header("Express"));
                    });
                };
            }
        }

        public static Action<ListItemFactory<CellGroup, CellGroupBuilder>> TwoLines
        {
            get
            {
                return ld =>
                {
                    ld.Add().Header("Order").Colspan(2).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Id").Header("ID").CssClass("id").Width("150"))
                            .Add(cell => cell.Binding("Date").Header("Ordered").Width("150"))
                            .Add(cell => cell.Binding("Amount").Header("Amount").Format("c").CssClass("amount"))
                            .Add(cell => cell.Binding("ShippedDate").Header("Shipped"));
                    });
                    ld.Add().Header("Customer").Colspan(3).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Customer.Name").Name("CustomerName").Header("Customer").Width("200"))
                            .Add(cell => cell.Binding("Customer.Email").Name("CustomerEmail").Header("Customer Email").Colspan(2).CssClass("email"))
                            .Add(cell => cell.Binding("Customer.Address").Name("CustomerAddress").Header("Address"))
                            .Add(cell => cell.Binding("Customer.City").Name("CustomerCity").Header("City").ShowDropDown(true)
                                .DataMap(dm => { dm.DisplayMemberPath("Value").SelectedValuePath("Value").Bind(Orders.GetCities().ToValues()); }))
                            .Add(cell => cell.Binding("Customer.State").Name("CustomerState").Header("State"));
                    });
                    ld.Add().Header("Shipper").Colspan(2).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Shipper.Name").Name("ShipperName").Header("Shipper").Colspan(2))
                            .Add(cell => cell.Binding("Shipper.Email").Name("ShipperEmail").Header("Shipper Email").Width("200").CssClass("email"))
                            .Add(cell => cell.Binding("Shipper.Express").Name("ShipperExpress").Header("Express"));
                    });
                };
            }
        }

        public static Action<ListItemFactory<CellGroup, CellGroupBuilder>> ThreeLines
        {
            get
            {
                return ld =>
                {
                    ld.Add().Header("Order").Colspan(2).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Id").Header("ID").Colspan(2).CssClass("id"))
                            .Add(cell => cell.Binding("Amount").Header("Amount").Format("c").Colspan(2).CssClass("amount"))
                            .Add(cell => cell.Binding("Date").Header("Ordered"))
                            .Add(cell => cell.Binding("ShippedDate").Header("Shipped"));
                    });
                    ld.Add().Header("Customer").Colspan(3).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Customer.Name").Name("CustomerName").Header("Customer"))
                            .Add(cell => cell.Binding("Customer.Email").Name("CustomerEmail").Header("Customer Email").Colspan(2).CssClass("email"))
                            .Add(cell => cell.Binding("Customer.Address").Name("CustomerAddress").Header("Address").Colspan(2))
                            .Add(cell => cell.Binding("Customer.Phone").Name("CustomerPhone").Header("Phone"))
                            .Add(cell => cell.Binding("Customer.City").Name("CustomerCity").Header("City")
                                .DataMap(dm => { dm.DisplayMemberPath("Value").SelectedValuePath("Value").Bind(Orders.GetCities().ToValues()); }))
                            .Add(cell => cell.Binding("Customer.State").Name("CustomerState").Header("State"))
                            .Add(cell => cell.Binding("Customer.Zip").Name("CustomerZip").Header("Zip"));
                    });
                    ld.Add().Header("Shipper").Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Shipper.Name").Name("ShipperName").Header("Shipper").Width("*"))
                            .Add(cell => cell.Binding("Shipper.Email").Name("ShipperEmail").Header("Shipper Email").CssClass("email"))
                            .Add(cell => cell.Binding("Shipper.Express").Name("ShipperExpress").Header("Express"));
                    });
                };
            }
        }

        public static Action<ListItemFactory<CellGroup, CellGroupBuilder>> Sales
        {
            get
            {
                return ld =>
                {
                    ld.Add().Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("ID").Header("ID"));
                        cells.Add(cell => cell.Binding("Active").Header("Active"));
                    });
                    ld.Add().Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Start").Header("Start"));
                        cells.Add(cell => cell.Binding("End").Header("End"));
                    });
                    ld.Add().Colspan(2).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Country").Header("Country").Colspan(2));
                        cells.Add(cell => cell.Binding("Product").Header("Product"));
                        cells.Add(cell => cell.Binding("Color").Header("Color"));
                    });
                    ld.Add().Colspan(2).Cells(cells =>
                    {
                        cells.Add(cell => cell.Binding("Amount").Header("Amount"));
                        cells.Add(cell => cell.Binding("Amount2").Header("Amount2"));
                        cells.Add(cell => cell.Binding("Discount").Header("Discount").Colspan(2));
                    });
                };
            }
        }
    }
}
using System.Web.Mvc;
using System.Collections.Generic;
using MultiRowExplorer.Models;

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(FormCollection collection)
        {
            _options.LoadPostData(collection);
            var model = Orders.GetOrders();
            ViewBag.DemoOptions = _options;
            return View(model);
        }
    }
}
@model IEnumerable<Orders.Order>
@{
    ControlOptions optionsModel = ViewBag.DemoOptions;
    ViewBag.DemoSettings = true;

    var layoutDefinition = optionsModel.Options["Layout Definition"].CurrentValue;
    Action<ListItemFactory<CellGroup, CellGroupBuilder>> layoutDefinitionBuilder;
    if (layoutDefinition == "Traditional")
    {
        layoutDefinitionBuilder = LayoutDefinitionsBuilders.OneLine;
    }
    else if (layoutDefinition == "Compact")
    {
        layoutDefinitionBuilder = LayoutDefinitionsBuilders.TwoLines;
    }
    else
    {
        layoutDefinitionBuilder = LayoutDefinitionsBuilders.ThreeLines;
    }
}

@(Html.C1().MultiRow<Orders.Order>()
    .Id("ovMultiRow")
    .Bind(bl => bl.Bind(Model).DisableServerRead(true))
    .CssClass("multirow")
    .LayoutDefinition(layoutDefinitionBuilder)
)
@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 format, just like other conventional grids.
        However, <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 cells in a 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>
        Here, 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>
}