Using Visual WebGui Gateways ina simpler way

In this article we are going to learn how to use Visual WebGui Gateways. Gateways are Visual WebGui way to declare virtual URLs that are handheld by a control according to declared actions. 
This topic assumes that you have some basic knowledge of Visual WebGui and How to create a Visual WebGui Custom control.

Up until version 6.2 Visual WebGui Gateways were a hard pill to swallow. What we’ve done was to simplify the implementation of Gateways.

Important: The new implementation of IGatewayComponent conflicts with the previous IGatewayControl interface. By default any control that implements an IGatewayControl will not be able to use the new IGatewayComponent interface for backwards compatibility reasons. The best practice is to gradually convert your IGatewayControl implementations to the new IGatewayComponent interface, which in most cases will mean that you will override the ProcessGatewayRequest method that is implemented by default in the Visual WebGui base classes as a overridable virtual method.

We’ve added a new interface IGatewayComponent that holds one method declaration ProcessRequest.

public interface IGatewayComponent

{

    /// <summary>

    /// Provides a way to custom handle requests.

    /// </summary>

    /// <param name="objContext">The request context.</param>

    /// <param name="strAction">The request action.</param>

    void ProcessRequest(IContext objContext, string strAction);

}

RegisteredComponent now inherits from IGatewayComponent and implements the ProcessRequest  Method.

void IGatewayComponent.ProcessRequest(IContext objContext, string strAction)

{

    // Trt to get the gateway handler

    IGatewayHandler objGatewayHandler = ProcessGatewayRequest(objContext.HttpContext,  strAction);

    if (objGatewayHandler != null)

    {

        objGatewayHandler.ProcessGatewayRequest(objContext, this);

    }

}

the ProcessRequest method calls the ProcessGatewayRequest method. This method returns a NotImplementedGateway by default.

protected virtual IGatewayHandler ProcessGatewayRequest(HttpContext objHttpContext, string strAction)

{

    return new NotImplementedGateway(strAction);

}

This allows you to override the ProcessGatewayRequest  method and return your own IGatewayHandler.

Because RegisteredComponent now inherits from IGatewayComponent every control in Visual WebGui out of the box controls and every control that you will create will implement the IGatewayComponent allowing you just to override the ProcessGatewayRequest and having your Gateway much faster then you used to.

Lets see how this works.

Let’s create a new custom control PieControl that will display a dynamic pie chart image.

image

Our control will inherit from “PictureBox” and will display the pie chart image. We will add two properties.
The first is an array of type int “Values” that will hold the values of our pie chart.
The second is an array of type string “Labels” that will hold the pie chart section labels.

public class PieControl : PictureBox

{

    private int[] dataValues = new int[]{};

    private string[] dataLabels = new string[]{};

    public int[] Values

    {

        get

        {

            return dataValues;

        }

        set

        {

            dataValues = value;

        }

    }

    public string[] Labels

    {

        get

        {

            return dataLabels;

        }

        set

        {

            dataLabels = value;

        }

    }

}

Next we will override the ProcessGatewayRequest function. In our control we create an image using the values and the labels and randomly selected colors .

protected override IGatewayHandler ProcessGatewayRequest(HttpContext objHttpContext, string strAction)

{

    // If is "graph" action print a graph to the response, otherwise let the base class handle the request.

    if (strAction == "graph")

    {

        // find the total of the numeric data

        float total = 100;

        int width = 300;

        string title = "What do we eat and drink?";

        int iLoop = 0;

        // we need to create fonts for our legend and title

        Font fontLegend = new Font("Verdana", 10), fontTitle = new Font("Verdana", 15, FontStyle.Bold);

        // We need to create a legend and title, how big do these need to be?

        // Also, we need to resize the height for the pie chart, respective to the

        // height of the legend and title

        const int bufferSpace = 15;

        int legendHeight = fontLegend.Height * (dataValues.Length + 1) + bufferSpace;

        int titleHeight = fontTitle.Height + bufferSpace;

        int height = width + legendHeight + titleHeight + bufferSpace;

        int pieHeight = width;    // maintain a one-to-one ratio

        // Create a rectange for drawing our pie

        Rectangle pieRect = new Rectangle(0, titleHeight, width, pieHeight);

        // Create our pie chart, start by creating an ArrayList of colors

        ArrayList colors = new ArrayList();

        Random rnd = new Random();

        for (iLoop = 0; iLoop < dataValues.Length; iLoop++)

            colors.Add(new SolidBrush(Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255))));

        float currentDegree = 0.0F;

        // Create a Bitmap instance   

        Bitmap objBitmap = new Bitmap(width, height);

        Graphics objGraphics = Graphics.FromImage(objBitmap);

        SolidBrush blackBrush = new SolidBrush(Color.Black);

        // Put a white backround in

        objGraphics.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);

        for (iLoop = 0; iLoop < dataValues.Length; iLoop++)

        {

            objGraphics.FillPie((SolidBrush)colors[iLoop], pieRect, currentDegree,

                dataValues[iLoop] / total * 360);

            // increment the currentDegree

            currentDegree += Convert.ToSingle(dataValues[iLoop]) / total * 360;

        }

        // Create the title, centered

        StringFormat stringFormat = new StringFormat();

        stringFormat.Alignment = StringAlignment.Center;

        stringFormat.LineAlignment = StringAlignment.Center;

        objGraphics.DrawString(title, fontTitle, blackBrush,

            new Rectangle(0, 0, width, titleHeight), stringFormat);

        // Create the legend

        objGraphics.DrawRectangle(new Pen(Color.Black, 2), 0, height - legendHeight, width, legendHeight);

        for (iLoop = 0; iLoop < dataValues.Length; iLoop++)

        {

            objGraphics.FillRectangle((SolidBrush)colors[iLoop], 5,

                height - legendHeight + fontLegend.Height * iLoop + 5, 10, 10);

            objGraphics.DrawString(dataLabels[iLoop], fontLegend, blackBrush,

                20, height - legendHeight + fontLegend.Height * iLoop + 1);

        }

        // display the total

        objGraphics.DrawString("Total: " + Convert.ToString(total), fontLegend, blackBrush,

            5, height - fontLegend.Height - 5);

        // Since we are outputting a Jpeg, set the ContentType appropriately

        HttpContext.Current.Response.ContentType = "image/jpeg";

        // Save the image to a file

        objBitmap.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Jpeg);

        // clean up...

        objGraphics.Dispose();

        objBitmap.Dispose();

        return null;

    }

    else

    {

        return base.ProcessGatewayRequest(objHttpContext, strAction);

    }

}       

}

To focus you to the most impotent part of the function where we save the result to the out put stream.

// Since we are outputting a Jpeg, set the ContentType appropriately

HttpContext.Current.Response.ContentType = "image/jpeg";

// Save the image to a file

objBitmap.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Jpeg);

In the constructor we will set the image value to a new GatewayResourceHandle that will return a resource handel using our ProcessGatewayRequest method.

public PieControl()

{

   this.Image = new GatewayResourceHandle(new GatewayReference(this, "graph"));

   this.SizeMode = PictureBoxSizeMode.Normal;

}

Now that we have our control lets us it in our application. Open Form1 and add the control. Set the values 10,20,30,15,5,20 and labels "Fish","Meat","Milk","Cookies","Wine","Eggs".

Next Let’s run the application and this what we plan to see.

image

To summarize:
We’ve seen how to use the new Visual WebGui Gateway implementation technic using the IGatewayComponent  that simplifies Gateways to just overriding one function and adding your code to it. This will help you create and customize your controls with virtual URLs.

You can read the original how to here 

-- Eyal Albert @ Eyal.Albert (at) Gizmox.com

No Comments