Building Sample GDI+ ApplicationsIn the following sections, you examine two ways to use GDI+ classes in an ASP.NET application. First, you build a simple paint application. The paint application enables you to draw complex images from a Web page. Next, you tackle a chart application. You create an application that enables you to automatically generate bar charts from database data. Creating an ASP.NET Paint ApplicationThis ASP.NET paint application enables you to draw objects with different colors and different shapes from a Web page (see Figure 27.16). The paint application consists of the following two files:
Figure 27.16. The ASP.NET Paint application.
Start by constructing the Painter.aspx page. The complete code for this page is contained in Listing 27.16. Listing 27.16 Painter.aspx<%@ Import Namespace="System.Drawing" %> <Script Runat="Server"> Sub Page_Load If Not IsPostBack Then ibtnCanvas.ImageUrl = "PaintImage.aspx" lstColor.DataSource = System.Enum.GetValues( GetType( KnownColor ) ) lstColor.SelectedIndex = 0 lstAction.SelectedIndex = 0 DataBind() End If End Sub Sub ibtnCanvas_Click( s As Object, e As ImageClickEventArgs ) Dim strQueryString As String strQueryString &= "a=" & lstAction.SelectedItem.Text strQueryString &= "&color=" & lstColor.SelectedItem.Text strQueryString &= "&x=" & e.X strQueryString &= "&y=" & e.y ibtnCanvas.ImageUrl = "PaintImage.aspx?" & strQueryString End Sub Sub btnClear_Click( s As Object, e As EventArgs ) Session( "Canvas" ) = Nothing ibtnCanvas.ImageURL = "PaintImage.aspx" End Sub </Script> <html> <head><title>Painter.aspx</title></head> <body> <form Runat="Server"> <table width="100%"> <tr><td valign="top"> <h3>Draw:</h3> <asp:ListBox ID="lstAction" Runat="Server" > <asp:ListItem Text="SetPixel" /> <asp:ListItem Text="DrawLine" /> <asp:ListItem Text="DrawRectangle" /> <asp:ListItem Text="FillRectangle" /> </asp:ListBox> <h3>Color:</h3> <asp:ListBox id="lstColor" Runat="Server" /> <p> <asp:Button id="btnClear" Text="Clear All" OnClick="btnClear_Click" Runat="Server" /> </td><td valign="top"> <asp:ImageButton id="ibtnCanvas" OnClick="ibtnCanvas_Click" Runat="Server" /> </td></tr> </table> </form> </body> </html> The C# version of this code can be found on the CD-ROM. The Painter.aspx page contains a form with four controls. The first control, the lstAction ListBox , enables you to select a particular drawing action. For example, you can choose to draw a line or rectangle. The second control, lstColor , is also a ListBox control. It enables you to select a color to use when drawing an object. The list of colors is retrieved from the KnownColor enumeration and bound to the ListBox control. The third control, the btnClear Button , enables you to clear the current image from memory and start over drawing a new image. Finally, the drawing canvas is represented by an ImageButton control named ibtnCanvas . The ImageURL property of the ImageButton control points to the PaintImage.aspx page. When you click any spot on the image, the ibtnCanvas_Click subroutine is executed. The ibtnCanvas_Click subroutine passes information to the PaintImage.aspx page through a query string. The subroutine passes four bits of information: the selected action, selected color, and x and y coordinates of the mouse click. The PaintImage.aspx page is contained in Listing 27.17. This page actually renders the image. Listing 27.17 PaintImage.aspx [View full width] <%@ Page ContentType="image/gif" %> <%@ Import namespace="System.Drawing" %> <%@ Import namespace="System.Drawing.Imaging" %> <Script Runat="Server"> Sub Page_Load Dim objBitmap As Bitmap Dim objGraphics As Graphics Dim objPen As Pen Dim strAction As String Dim strColor As String Dim objColor As Color Dim intOldX, intOldY As Integer Dim intNewX, intNewY As Integer ' Create or Retrieve Bitmap objBitmap = Session( "Canvas" ) If objBitmap Is Nothing Then objBitmap = New Bitmap( 600, 400, PixelFormat.Format32bppARGB ) End If objGraphics = Graphics.FromImage( objBitmap ) ' Get Action, Color, and Coordinates strAction = Request.QueryString( "a" ) strColor = Request.QueryString( "color" ) intNewX = Request.QueryString( "x" ) intNewY = Request.QueryString( "y" ) intOldX = Session( "OldX" ) intOldY = Session( "OldY" ) ' Create Pen If strColor <> Nothing Then objColor = Color.FromName( strColor ) objPen = New Pen( objColor ) Else objColor = Color.White objPen = New Pen( objColor ) End If ' Perform Action Select Case strAction Case "SetPixel" objBitMap.SetPixel( intNewX, intNewY, objColor ) Case "DrawLine" If intOldX <> Nothing Then objGraphics.DrawLine( objPen, intOldX, intOldY, intNewX, intNewY ) End If Case "DrawLine" If intOldX <> Nothing Then objGraphics.DrawLine( objPen, intOldX, intOldY, intNewX, intNewY ) End If Case "DrawRectangle" If intOldX <> Nothing Then objGraphics.DrawRectangle( objPen, intOldX, intOldY, intNewX - intOldX, intNewY - intOldY ) End If Case "FillRectangle" If intOldX <> Nothing Then objGraphics.FillRectangle( New SolidBrush( objColor ), intOldX, intOldY, intNewX - intOldX, intNewY - intOldY ) End If End Select ' Display the Bitmap objBitmap.Save( Response.OutputStream, ImageFormat.GIF) ' Save the Bitmap Session( "Canvas" ) = objBitMap If Session( "OldX" ) <> Nothing Then Session( "OldX" ) = Nothing Session( "OldY" ) = Nothing Else Session( "OldX" ) = intNewX Session( "OldY" ) = intNewY End If End Sub </Script> The C# version of this code can be found on the CD-ROM. The PaintImage.aspx page starts by checking whether a bitmap already exists in session state. If the bitmap does not exist, it is created. The image is saved to session state between requests to the Web server. This step is necessary to preserve any modifications made to the image. NOTE To learn more information about session state, see Chapter 16, "Tracking User Sessions." Next, all the information passed in the query string from the Painter.aspx page is retrieved. The selected action, selected color, and x and y coordinates are all assigned to local variables . The bulk of the code for the PaintImage.aspx page is devoted to a Select...Case statement. This statement performs different modifications to the image, depending on the selected action. For example, if the selected action is DrawLine , a line is rendered on the image. The image is actually displayed when the bitmap is rendered to the output stream of the Response object. The image is displayed by the ImageButton control in the Painter.aspx page. Finally, the image is saved into session state. Placing the image into session state preserves the image until PaintImage.aspx is requested again. Creating a Simple Chart ApplicationIn this section, you build a simple chart application that enables you to display bar charts in a Web page (see Figure 27.17). The chart application consists of the following three files:
Figure 27.17. The chart application.
Start with the TestChart.aspx page because it gives you an idea of how the overall chart application works. The complete code for this page is included in Listing 27.18. Listing 27.18 TestChart.aspx<%@ Register TagPrefix="myControl" TagName="Chart" SRC="chart.ascx" %> <%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Sub Page_Load Dim conPubs As SQLConnection Dim cmdSelect As SQLCommand conPubs = New SQLConnection( "Server=localhost;UID=sa;PWD=secret; database=Pubs" ) cmdSelect = New SQLCommand( "Select ytd_sales From Titles", conPubs ) conPubs.Open() ctrlChart.DataSource = cmdSelect.ExecuteReader() ctrlChart.DataField = "ytd_sales" ctrlChart.DataBind() conPubs.Close End Sub </Script> <html> <head><title>TestChart.aspx</title></head> <body> <h2>Year-To-Date Sales</h2> <myControl:Chart id="ctrlChart" BackColor="Orange" ForeColor="Purple" Runat="Server" /> </body> </html> The C# version of this code can be found on the CD-ROM. The first line in the TestChart.aspx page registers the Chart.ascx user control with the TagPrefix named myControl and TagName named Chart . The Chart control is instantiated in the body of the page with an ID of ctrlChart . The Chart control is bound to a database table in the Page_Load subroutine. This subroutine opens a database connection and creates a DataReader that represents records from the Titles table. The DataReader is bound to the Chart control with the help of the DataSource property. You should notice that the DataField property of the Chart control is set. This property indicates the field from the DataReader that contains the data to be charted. Finally, notice that the Chart control is declared with an orange backcolor and a purple forecolor. The Chart control renders a purple bar chart against an orange background. (You can, of course, change these color values to anything you want.) The source of the Chart user control is contained in Listing 27.19. Listing 27.19 Chart.ascx<Script Runat="Server"> Public DataSource As IEnumerable Public DataField As String Public BackColor As String = "White" Public ForeColor As String = "Blue" Protected Overrides Sub OnDataBinding( e As EventArgs ) Dim objDataEnum As IEnumerator Dim objDataItem As Object Dim strUrl As String Dim intMaxData As Integer If Not DataSource Is Nothing And DataField <> Nothing Then objDataEnum = DataSource.GetEnumerator() Do While( objDataEnum.MoveNext() ) objDataItem = DataBinder.Eval( objDataEnum.Current, DataField ) If IsNumeric( objDataItem ) Then strUrl &= "&d=" & Server.UrlEncode( objDataItem.ToString ) If objDataItem > intMaxData Then intMaxData = objDataItem End If Loop strUrl = "x=" & intMaxData & "&backcolor=" & BackColor & "&forecolor=" & ForeColor & strUrl imgChartImage.ImageURL = "ChartImage.aspx?" & strURL End If End Sub </Script> <asp:Image ID="imgChartImage" Runat="Server" /> The C# version of this code can be found on the CD-ROM. The Chart user control has four public properties. DataField represents the field in the DataSource that contains the data to be charted. DataSource contains the actual data. The BackColor and ForeColor properties indicate the colors used when rendering the bar chart. The DataSource property implements the IEnumerable interface. Because the DataReader implements the IEnumerable interface, you can bind data from a DataReader to the Chart control. The bulk of the code for the Chart.ascx user control is contained in the OnDataBinding subroutine. This subroutine is invoked when the DataBind method is called in the TestChart.aspx page. The OnDataBinding subroutine steps through all the data from the DataSource to build a query string. For example, assume that the DataSource contains the following values: 23.45, 89.12, 78, 22.12 In this case, the following query string is constructed : d=23.45&d=89.12&d=78&d=22.12 After the query string is built, three additional query string variables are added to the beginning of it: x , BackColor , and ForeColor . The x variable represents the maximum value from the DataSource . You use this value when scaling the bar chart. Finally, the query string is passed to an Image control, which displays the image rendered by the ChartImage.aspx page. The complete code for the ChartImage.aspx page is contained in Listing 27.20. Listing 27.20 ChartImage.aspx<%@ Page ContentType="image/gif" %> <%@ Import Namespace="System.Drawing" %> <%@ Import Namespace="System.Drawing.Imaging" %> <Script Runat="Server"> Sub Page_Load Dim objBitmap As Bitmap Dim objGraphics As Graphics Dim decMaxData As Decimal Dim strBackColor As String Dim strForeColor As String Dim objBackColor As Color Dim objForeColor As Color Dim decMultiplier As Decimal Dim intWidth As Integer Dim intHeight As Integer Dim arrChartData() As String Dim intDataIndex As Integer Dim intDataItem As Integer Dim objBrush As SolidBrush ' Calculate Multiplier decMaxData = Request.QueryString( "x" ) decMultiplier = 100 / decMaxData ' Retrieve Colors strBackColor = Request.QueryString( "backcolor" ) strForeColor = Request.QueryString( "forecolor" ) objBackColor = ColorTranslator.FromHTML( strBackColor ) objForeColor = ColorTranslator.FromHTML( strForeColor ) objBrush = New SolidBrush( objForeColor ) ' Build Bar Chart arrChartData = Request.QueryString.GetValues( "d" ) intWidth = ( arrChartData.Length * 15 ) + 10 intHeight = ( decMaxData * decMultiplier ) + 5 If Not arrChartData Is Nothing Then objBitmap = New Bitmap( intWidth, intHeight ) objGraphics = Graphics.FromImage( objBitmap ) objGraphics.Clear( objBackColor ) For intDataIndex = 0 To arrChartData.Length - 1 intDataItem = arrChartData( intDataIndex ) * decMultiplier objGraphics.FillRectangle( _ objBrush, _ ( intDataIndex * 15 ) + 5, _ intHeight - intDataItem, _ 10, _ intHeight ) Next objBitmap.Save( Response.OutputStream, ImageFormat.GIF ) End If End Sub </Script> The C# version of this code can be found on the CD-ROM. The ChartImage.aspx page retrieves all the information from the query string. All the data to be charted is assigned to a string array named ChartArray . Next, a bitmap is created, and the Clear method is called to set the background color. A For...Next loop steps through all the elements in arrChartData . A rectangle is drawn for each element with the FillRectangle method. Finally, the bitmap is saved to the output stream of the Response object. At this point, the bar chart is displayed. |