DocuVieware Reference Guide
Custom Snap-In implementation using a MVC PartialView
Tutorials > ASP.NET MVC Razor > Custom Snap-In implementation using a MVC PartialView
This tutorial is an alternative to this one, as such, it assumes that you have fully followed the Your first DocuVieware MVC Razor page tutorial first as its starting point is the end of it.
 Overview
       

As seen in this tutorial, Snap-Ins are very powerful interface elements that provide a rich and modular user experience. Depending on your custom Snap-In content it can quickly become tedious to design and also painful to maintain.
In this context the best option is to build the custom Snap-In in an MVC PartialView (thanks to Jocke Pihlström for the idea and his help on the subject).

You are going to implement a Custom Snap-In that will contain a simple button which action will be to send a "ping" command to the server and it will reply with a "pong" message using the MVC PartialView concept.

DocuVieware™ requires .NET Framework 4.6 or above.
The screenshots have been taken using Visual Studio 2015 and GdPicture.NET™ 14, it may differ from the current release.

Summary

 Preparing the PartialView implementation

Step 1: Create a ViewModel that will contain both DocuVieware™ unique ID and your custom Snap-In HTML content.

public class IndexViewModel
{
    public string DocuViewareID { get; set; }
    public string SnapInHtmlContent { get; set; }
}

Step 2: Create an extension method that will allow you to render your newly created PartialView to a string. To do this, simply create a new RenderRazorViewToStringHelper.cs class.

public static class RenderRazorViewToStringHelper
{
   public static string RenderRazorViewToString(this Controller controller, string viewName, object model)
   {
      controller.ViewData.Model = model;
      using (StringWriter stringWriter = new StringWriter())
      {
         ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
         ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, stringWriter);
         viewResult.View.Render(viewContext, stringWriter);
         viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);
         return stringWriter.GetStringBuilder().ToString();
      }
   }
}
   
 Creating the Snap-In content as a PartialView

Step 1: Create a PartialView called _CustomSnapIn.cshtml with the following content:

@model IndexViewModel

<div id="customSnapInTutorialPanel@(Model.DocuViewareID)">
   <div style="float:left; margin-top:6px; margin-left:6px">
      <button id="customSnapInSubmit@(Model.DocuViewareID)" style="height:26px" class="btn-valid" onclick="ping(); return false;">Ping</button>
   </div>
</div>

<script>
   function ping() {
      DocuViewareAPI.PostCustomServerAction('@(Model.DocuViewareID)', true, 'ping');
   }
</script>

Step 2: Getting back to your controller, in the action you now need to take care of both the model creation and the PartialView rendering.

IndexViewModel model = new IndexViewModel { DocuViewareID = "DocuVieware1" };
model.SnapInHtmlContent = this.RenderRazorViewToString("_CustomSnapIn", model);
return View(model);

As you can see the created model is used to render the PartialView and it is then reinjected in the view where you have your DocuVieware™ control.

Step 3: In the view where you have your DocuVieware™ control (Index in the present case) you now need to first inject the model and then add the Snap-In from its content.

@model IndexViewModel

…

@{
   GdPicture14.WEB.DocuVieware docuVieware = new GdPicture14.WEB.DocuVieware
   {
      ID = Model.DocuViewareID,
      Height = new System.Web.UI.WebControls.Unit("100%"),
      Width = new System.Web.UI.WebControls.Unit("100%")
   };
   using (HtmlGenericControl icon = new HtmlGenericControl("svg"))
   {
      icon.Attributes["viewBox"] = "0 0 16 16";
      icon.Attributes["width"] = "100%";
      icon.Attributes["height"] = "100%";
      icon.InnerHtml = "<path d=\"M6 0l-6 8h6l-4 8 14-10h-8l6-6z\"></path>";
      using (HtmlGenericControl panel = new HtmlGenericControl("div"))
      {
         panel.ClientIDMode = ClientIDMode.Static;
         panel.InnerHtml = Model.SnapInHtmlContent;
         docuVieware.AddCustomSnapIn("customSnapInTutorial", "Custom Snap-In", icon, panel, true);
      }
   }
   docuVieware.RenderControl(Output);
}
 Handling your action server side

As seen in the Client/Server coming and going with Custom Actions tutorial, you are going to implement a simple custom action that will process the snap-in button click event.

All you need to do now is add the custom action event handler in the Global.asax.cs file like this:

private void CustomActionsHandler(object sender, CustomActionEventArgs e)
{
   if ((e.actionName == "ping"))
   {
      e.message = new DocuViewareMessage("Pong", icon: DocuViewareMessageIcon.Information);
   }
}

Compile and start the page, the custom Snap-In icon will appear in the left panel.

Now, if you select it and click on the ping button, it will trigger the custom action and you should see a "Pong" message coming back from the server.

See Also