Getting Started: Building an Extension

You are here:

Creating a .NET Class Library

You can download Visual Studio Template (C#) and start working on a project right away or create your own project, step-by-step. Extension Template includes both base extension class and the config file.

Extension Template:

Extension Template Link: PagosExtensionTemplate.zip

To use Visual Studio Templates;

  1. Copy the template file to Visual Studio’s templates folder (default: \My Documents\Visual Studio Version\Templates\ProjectTemplates\Language\)
  2. Run Visual Studio
  3. On the File menu, click New, and then click Project.
  4. Select template name (eg. PagosExtensionTemplate) under Templates > Visual C#

Detailed information: https://msdn.microsoft.com/en-us/library/y3kkate1.aspx

Steps:

If you decided to use template please continue from 6th item.

  1. Prepare your Excel file and convert it via SpreadsheetWeb Wizard Add-in. As a result; you can use
  2. Download SpreadsheetWebIO.dll from here and add it to the Extension Library Project:
    using SpreadsheetWebIO
    
  3. If you are using SpreadsheetWeb 4.6 or above version; add ISSWebExtension to add Application_Init method:
    public interface ISSWebExtension : SpreadsheetWebIO.ISSWebExtension
    {
        string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
    
  4. Define extension class which should implement the interface ISSWebExtension from SpreadsheetWebIO:
    public class ExtensionExample : ISSWebExtension
    {
     ...
    }
    
  5. Add all of event methods into extension class. Following code sample also includes stubs to compile code without errors:
    public string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    public string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
    {
        var ret = "";
        executeSSWeb = true;
        outputs_ = null;
        return ret;
    }
    public string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
    {
        var ret = "";
        executeSSWeb = true;
        outputs_ = null;
        return ret;
    }
    public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
    {
        var ret = "";
        executeSSWeb = true;
        outputs_ = null;
        return ret;
    }
    public string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
    {
        var ret = "";
        outputs_ = null;
        return ret;
    }
    

     

  6. We are ready to start our own coding. Let’s say we have an application with 2 numeric inputs and want to calculate and write their sum value into a label:
    public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
    {
        var ret = "";
        executeSSWeb = false; // we don't want to triggering whole calculation
        outputs_ = new Dictionary<string, Dictionary<string, string>>(); // we will have outputs
        //INPUTS
        string inp_0_0 = inputs_["PSWInput_0_0"];
        string inp_0_1 = inputs_["PSWInput_0_1"];
        //CALCULATION
        double result = Double.Parse(inp_0_0) + Double.Parse(inp_0_1);
        //OUTPUTS
        outputs_.Add("PSWTab_0.Label_2_8", new Dictionary<string, string> { { "text", result.ToString() } });
        //KEEP INPUTS
        foreach (string current in inputs_.Keys)
        {
            outputs_.Add(current, new Dictionary<string, string> { { "value", inputs_[current] } });
        }
        return ret;
    }
    
    Value_Changed method is used because we wanted to trigger extension as we enter input. 
    We can also use Button_Clicked to get result as a result of button click or Tab_Changed 
    if we want calculations while tab is changed.
  7. Compile project to create extension library .dll file.
  8. Prepare config file. Be sure set true for used methods. Config file is an XML file which is saved as .config file. Sample name: Extension.config
    <?xml version="1.0" encoding="utf-8" ?>
    <ExtensionConfig>
     <Type>Extension</Type>
     <Namespace>Extension</Namespace>
     <Class>Extension</Class>
     <Before_Value_Changed>false</Before_Value_Changed>
     <Value_Changed>true</Value_Changed>
     <After_Value_Changed>false</After_Value_Changed>
     <Before_Button_Click>false</Before_Button_Click>
     <Button_Click>true</Button_Click>
     <After_Button_Click>false</After_Button_Click>
     <Before_Tab_Changed>false</Before_Tab_Changed>
     <Tab_Changed>true</Tab_Changed>
     <After_Tab_Changed>false</After_Tab_Changed>
     <Application_Init>false</Application_Init>
     <Debug>false</Debug>
     <DebugFile>Extension.dll</DebugFile>
    </ExtensionConfig>
    
  9. Last step is combine .dll and .config file into a .zip archive and upload it to SpreadsheetWeb server. You can add an extension onto a file from Edit Application Page.

Full sample code:
using System;
using System.Collections.Generic;
using SpreadsheetWebIO;
namespace ExtensionTemplate
{
    public interface ISSWebExtension : SpreadsheetWebIO.ISSWebExtension
    {
        string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
        string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb);
        string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_);
    }
    public class Extension : ISSWebExtension
    {
        public string After_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string After_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string After_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string Before_Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string Before_Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string Before_Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
        public string Button_Click(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
        {
            var ret = "";
            executeSSWeb = true;
            outputs_ = null;
            return ret;
        }
        public string Tab_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
        {
            var ret = "";
            executeSSWeb = true;
            outputs_ = null;
            return ret;
        }
        public string Value_Changed(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_, out bool executeSSWeb)
        {
            var ret = "";
            executeSSWeb = false; // we don't want to triggering whole calculation
            outputs_ = new Dictionary<string, Dictionary<string, string>>(); // we will have outputs
            //INPUTS
            string inp_0_0 = inputs_["PSWInput_0_0"];
            string inp_0_1 = inputs_["PSWInput_0_1"];
            //CALCULATION
            double result = Double.Parse(inp_0_0) + Double.Parse(inp_0_1);
            //OUTPUTS
            outputs_.Add("PSWTab_0.Label_2_8", new Dictionary<string, string> { { "text", result.ToString() } });
            //KEEP INPUTS
            foreach (string current in inputs_.Keys)
            {
                outputs_.Add(current, new Dictionary<string, string> { { "value", inputs_[current] } });
            }
            return ret;
        }
        public string Application_Init(string vjsClientId_, string sender_, Dictionary<string, string> queryStrings_, ref Dictionary<string, string> inputs_, out Dictionary<string, Dictionary<string, string>> outputs_)
        {
            var ret = "";
            outputs_ = null;
            return ret;
        }
    }
}