New Document
ASP.NET Multi Views

MultiView and View controls allow you to divide the content of a page into different groups, displaying only one group at a time. Each View control manages one group of content and all the View controls are held together in a MultiView control.

The MultiView control is responsible for displaying one View control at a time. The View displayed is called the active view.

MultiView is a simpler way to declare multiple views ( is a separate control that is used as a child control of MultiView control) and show only one at a time. It has no default interface like Calendar, you get only whatever you add in its different views. When it is rendered on the page, it is implemented through the HTML tag you place inside views.


You can navigate through views either by setting its ActiveViewIndex property or by putting buttons with preset command names. To Navigate through different views, you need to put Buttons/LinkButton/ImageButton on the views with CommandName as NextView(to navigate to next view) and PrevView(to navigate to previous view).

The syntax for a MultiView control is:

<asp:MultView ID= "MultiView1" runat= "server"></asp:MultiView>

The syntax for a View control is:

<asp:View ID= "View1" runat= "server"></asp:View>

However, the View control cannot exist on its own. It would render error if you try to use it stand-alone. It is always used with a Multiview control as:

<asp:MultView ID= "MultiView1" runat= "server">
<asp:View ID= "View1" runat= "server"> </asp:View>
</asp:MultiView>

One of the requirements of our multi-tenant application, is having the ability to replace or add new pages (or parts of pages) in the system for each of our modules.

While a customer may ask for an entirely new 'area' on the site (MVC2 covers this), the chances are they just want the addition of a single page or replacement of what is already provided in the stock product.

The obvious port of call for change of this kind are the views and partial views situated within the web application, and finding a way to add or override these on a per-module basis.

Throughout the following entry I'll assume we have access to a configuration provider that looks something like this:

public interface IConfigurationProvider
{
    Configuration GetActiveConfiguration();
}
Where Configuration has the following simplistic structure (for demo purposes)
    public class Configuration
    {
        public string Theme
        {
            get;
            set;
        }

        public Module[] Modules
        {
            get;
            set;
        }
    }

    public class Module
    {
        public string Id
        {
            get;
            set;
        }
    }

In other words, we have a way of querying for the 'currently active configuration' (remember, our active configuration is per-request because we're attempting true multi-tenancy), and our configuration consists of a single theme and a list of loaded modules.

Each module has an Id and we'll use this to infer a number of things by convention. (Again, this is just a demo, and you can do this however you like.)

I assume each module will provide a collection of views and partial views, and if a module is loaded *after* another module, and provides another view or partial view with the same name and path, it will replace the previously loaded view or partial view.

I was asked in a comment on a previous entry what my folder structure looked like, and this is where the folder structure starts to become important.

Collapsed views

Every module's views come packaged in a single directory, with another directory called Views inside of it.

Underneath each of these Views directories, is the same folder structure you'd expect from a traditional ASP.NET MVC Website, with a directory per controller and a collection of views and partial views.

This means that both Core and ModuleOne can contribute or replace views for the actions from the "Home" Controller.

A thing of note, is that the web.config file that would ordinarily live in the Views directory in a traditional ASP.NET MVC application has been moved out into the Site directory above all the module directories - as this does things like give you Intellisense in your views (if I recall correctly) as well as actually facilitating the functionality in the ASP.NET MVC Framework.

Expanded, our project looks like this:

Expanded folder selection

Assuming the partial view "Widget" is exposed somewhere on the Index page, the following desired scenarios present themselves:

Core Module loaded:

/Home/Index requested => Index served from CoreModule, with Widget from CoreModule
/Home/Extra requested => Page not found

Core + ModuleOne Loaded (in that order)

/Home/Index requested => Index served from CoreModule with Widget from ModuleOne
/Home/Extra requested => Extra served from ModuleOne

ModuleOne + Core Loaded (in that order)

/Home/Index requested => Index served from CoreModule with Widget from CoreModule
/Home/Extra requested => Extra served from ModuleOne
Properties of the View and MultiView controls

Both the View and MultiView controls are derived from Control class and inherits all its properties, methods and events. The most important property of the View control is Visible property of type Boolean, which sets the visibility of a view.

The MultiView control has the following important properties:

PropertiesDescription
ViewsCollection of View controls within the MultiView
ActiveViewIndexA zero based index that denotes the active view; if no view is active then the index is -1.

The CommandName attribute of the Button controls associated with the navigation of the MultiView control are associated with some related field of the MultiView control.

For example, if a Button control with CommandName value as NextView is associated with the navigation of the multiview, it automatically navigates to the next view when the button is clicked.

The following table shows the default command names for the above properties:

PropertiesDescription
NextViewCommandNameNextView
PreviousViewCommandNamePrevView
SwitchViewByIDCommandNameSwitchViewByID
SwitchViewByIndexCommandNameSwitchViewByIndex

The following are the important methods of the MultiView control:

MethodsDescription
SetActiveviewSets the active view
GetActiveviewRetrieves the active view

Every time a view is changed, the page is posted back to the server and a number of events are raised. Some important events are:

EventsDescription
ActiveViewChanged Raised when a view is changed
Activate Raised by the active view
Deactivate Raised by the inactive view

Apart from the above mentioned properties, methods and events, multi view control inherits the members of the control and object class.

Example:

The example page has three views. Each view has two button for navigating through the views.

The content file is as follows:

<%@ Page Language="C#" 
         AutoEventWireup="true" 
         CodeBehind="Default.aspx.cs" 
         Inherits="multiviewdemo._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>

<h2>MultiView and View Controls</h2>
    <asp:DropDownList ID="DropDownList1" 
         runat="server" 
     onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<hr />
<asp:MultiView ID="MultiView1" 
         runat="server" 
         ActiveViewIndex="2"
         onactiveviewchanged="MultiView1_ActiveViewChanged" >
<asp:View ID="View1" runat="server">

<h3>This is view 1</h3>
<br />
<asp:Button CommandName="NextView" ID="btnnext1" 
         runat="server" Text = "Go To Next" />

<asp:Button CommandArgument="View3" 
         CommandName="SwitchViewByID" ID="btnlast" 
         runat="server" Text = "Go To Last" />
</asp:View> 
<asp:View ID="View2" runat="server">

<h3>This is view 2</h3>
<asp:Button CommandName="NextView" ID="btnnext2" 
         runat="server" Text = "Go To Next" />
<asp:Button CommandName="PrevView" ID="btnprevious2" 
         runat="server" Text = "Go To Previous View" />
</asp:View> 
<asp:View ID="View3" runat="server">

<h3> This is view 3</h3>
<br />
<asp:Calendar ID="Calender1" runat="server"></asp:Calendar>
<br />
<asp:Button  CommandArgument="0" 
          CommandName="SwitchViewByIndex" ID="btnfirst" 
          runat="server" Text = "Go To Next" />
<asp:Button CommandName="PrevView" ID="btnprevious" 
runat="server" Text = "Go To Previous View" />
</asp:View> 
</asp:MultiView>
</div>
</form>
</body>
</html>


Previous                                                                                                                                                       Next