Skip to main content

Templates

  • 6 minutes to read

Templates allow you to quickly extend built-in functionality and introduce new capabilities with minimum effort. The DevExpress MVC extensions provide you with the ability to create templates for various extension elements.

Templates can be defined at different object levels at the same time (e.g., at the extension level and the item level). In this case, templates created at a lower level in the logical tree take precedence over other templates for the same element created at a higher level (e.g., a template defined at the item level has precedence over the same element template created at the extension level).

The Set[ElementName]TemplateContent methods are provided to define an element template.

Define templates in partial view pages

For each template type you want to use, create a Partial View (a .cshtml or .vbhtml) and provide it with the required content markup. To use this Partial View within a template, call the Html.RenderPartial helper method in template implementation.

Note that the method delegates that enable you to implement templates give you access to a container object within which a template is instantiated. A template container object typically exposes useful information identifying the templated element (for instance, for a grid column header these might be the corresponding column, the header’s current location - in the header section, Group Panel, or Customization Window, etc.). Depending upon your application logic, you may or may not use this information when composing templates. The following options are available.

Without Passing a Template Container

If a template is simple and its content does not depend on the information provided by a template container, you do not have to pass a template container object to a partial view. You can define the template contents by using a HTML markup.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add("Google", "google", "", "http://www.google.com/");
    settings.Items.Add().SetTextTemplateContent(container => { 
        Html.RenderPartial("MyMenuItem"); });
}).GetHtml()

Partial View (“MyMenuItem”):

<a href="http://www.bing.com/">Bing</a>

Note that you can do this more easily by using another method overload that accepts a string as a parameter.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add("Google", "google", "", "http://www.google.com/");
    settings.Items.Add().SetTextTemplateContent("<a href='http://www.bing.com/'>Bing</a>");
}).GetHtml()

Pass a Template Container as a Model to a Partial View

If you dynamically compose a template based on template container information, you can pass a template container object to a partial view page as a Model. Use the Html.RenderPartial method’s model parameter for this purpose.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add("Google", "google", "", "http://www.google.com/");
    settings.Items.Add("Bing", "bing", "", "http://www.bing.com/");
    settings.SetItemTextTemplateContent(container => {
        Html.RenderPartial("MyMenuItem", container);
    });
}).GetHtml()

Partial View (“MyMenuItem”):

@model MenuItemTemplateContainer

<a href=@Model.Item.NavigateUrl>
    @if (Model.Item.Name == "bing") { <b>Try @Model.Item.Text</b> }
    else { @Model.Item.Text }
</a>

Pass Template Container via ViewData

You can also pass a template container object to a partial view page as a part of the ViewData by using the Html.RenderPartial method’s viewData parameter.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add("Google", "google", "", "http://www.google.com/");
    settings.Items.Add("Bing", "bing", "", "http://www.bing.com/");
    settings.SetItemTextTemplateContent(container => {
        ViewData["Container"] = container;
        Html.RenderPartial("MyMenuItem", ViewData);
    });
}).GetHtml()

Partial View (“MyMenuItem”):

@{ var container = ViewData["Container"] as MenuItemTemplateContainer; }

<a href=@container.Item.NavigateUrl>
    @if (container.Item.Name == "bing") { <b>Try @container.Item.Text</b> }
    else { @container.Item.Text }
</a>

Define templates in delegate methods directly

If you do not want to use partial views for some reason, and need to entirely define template contents within a delegate method implementation, you can do this using the following options.

Use DevExpress extensions as child controls

You can safely compose a template with the use of DevExpress extensions, which can be rendered with either the ExtensionBase.Render or ExtensionBase.GetHtml method.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add().SetTextTemplateContent(container => {
        Html.DevExpress().Label(labelSettings => {
            labelSettings.Text = "Google";
        }).GetHtml();
    });
    settings.Items.Add().SetTextTemplateContent(container =>{
        Html.DevExpress().HyperLink(linkSettings => {
            linkSettings.Properties.Text = "Bing";
            linkSettings.NavigateUrl = "http://www.bing.com/";
        }).Render();
    });    
}).GetHtml()

Use ViewContext.Writer.Write

If you need to use expressions and an HTML markup, and then combine them with server code within template contents, you can embed a HTML markup by using the ViewContext.Writer.Write method.

View:

@Html.DevExpress().Menu(settings => {
    settings.Name = "myMenu";
    settings.Items.Add("Google", "google", "", "http://www.google.com/");
    settings.Items.Add("Bing", "bing", "", "http://www.bing.com/");
    settings.SetItemTextTemplateContent(container => {
        if (container.Item.Name == "bing"){
            ViewContext.Writer.Write("<a href=" + @container.Item.NavigateUrl + "><b>" + Html.Label("", "Try " + @container.Item.Text) + "</b></a>");
        }
        else {
            Html.DevExpress().HyperLink(linkSettings =>{
                linkSettings.Properties.Text = container.Item.Text;
                linkSettings.NavigateUrl = container.Item.NavigateUrl;
            }).Render();                
        }
    });
}).GetHtml()

Use HtmlHelper class

You can implement an extension method for the HtmlHelper in order to access it in the Controller (not a View) scope. To implement this functionality, you may pass an HtmlHelper object to some static method that creates DevExpress extension settings with templates. At first, you may create some class to get extension settings shared between Views.

Controller code:

public static class GridViewHelper {
     public static GridViewSettings GetInlineEditingSettings(this HtmlHelper htmlHelper){
          GridViewSettings settings = new GridViewSettings();
          settings.Name = "gvEditingWithTemplate";
          settings.KeyFieldName = "ProductID";
          ...
          settings.SetEditFormTemplateContent(c => {
               var product = htmlHelper.ViewData["EditableProduct"] != null ? htmlHelper.ViewData["EditableProduct"] : c.DataItem;
               htmlHelper.ViewContext.Writer.Write(
                    "<div class=\"edit_form\">" +
                    "<div class=\"line\">"
               );
               htmlHelper.DevExpress().Label(
                    edtSettings => {
                         edtSettings.ControlStyle.CssClass = "label";
                         edtSettings.Text = "Product Name:";
                         edtSettings.AssociatedControlName = "ProductName";
               }).Render();
               htmlHelper.DevExpress().TextBox(
                    edtSettings => {
                         edtSettings.Name = "ProductName";
                         edtSettings.ControlStyle.CssClass = "editor";
                         edtSettings.ShowModelErrors = true;
               }).Bind(DataBinder.Eval(product, "ProductName")).Render();
               htmlHelper.ViewContext.Writer.Write(
                    "</div>" +
                    "<div class=\"line\">"
               );
               ...
          });
          return settings;
     }
}

After writing methods to get the settings, you may use this class in various Partial Views as your needs dictate.

Partial view code (ASPX):

@{
     var grid = Html.DevExpress().GridView(Html.GetInlineEditingSettings());
     if(ViewData["EditError"] != null){
          grid.SetEditErrorText((string)ViewData["EditError"]);
     }
}
@grid.Bind(Model).GetHtml()