Get the Most Out of Windows Forms Controls
Create Rich User Interfaces by Injecting Windows Forms Controls into Your ASP.NET Web Pages
October 30, 2009
ControlFreak
LANGUAGES:VB.NET | C#
ASP.NETVERSIONS: 1.x
Get the Most Out of Windows Forms Controls
Create Rich User Interfaces by Injecting Windows Forms Controlsinto Your ASP.NET Web Pages
By Steve C. Orr
Developers love Web applications because they are easierto deploy than Windows applications. But developers love Windows applicationsbecause functionally rich user interfaces can be created rapidly. Wouldn t itbe nice to have the best of both worlds? In this article I ll show you how youcan have your cake and eat it too by supercharging your ASP.NET Web pages withWindows Forms controls.
Why Use Windows Forms Controls?
There are many examples of things that can be done easilywith Windows Forms controls that would be difficult or impossible with Webcontrols alone. For example, there is no Web control that provides the richfunctionality of the Windows Forms ComboBox control. So what s to stop adeveloper from using the ComboBox control on their Web forms? Not much, as willbe demonstrated shortly. The custom ComboBox control defined in this articlecan even fetch its own data from a Web service.
How about interactive images that can constantly redrawand keep themselves up do date? The Bar Graph custom Windows control detailedlater in this article will demonstrate a mesmerizing animated bar chart thatcan redraw itself based on user input without having to call back to theserver.
Browser and .NET Framework Detection
Every user will need two things to successfully consume WindowsForms controls in a Web page: Internet Explorer and the .NET Framework. Theserequirements shouldn t be hard to meet these days, but there will sometimes bea minority of users who don t meet the requirements. Luckily, as a developer,you can help them find their way. A few lines of code are all it takes toverify the user has Internet Explorer and the .NET Framework installed; if theydon t, you can redirect them to an alternate page or guide them toward asolution:
Dim msg As String
If Request.Browser.Browser.ToUpper().IndexOf("IE") >=0 Then
IfRequest.Browser.ClrVersion.Major > 0 Then
Msg ="Your browseris good and powerful."
Else
msg ="Get the .NETFramework from www.WindowsUpdate.com"
End If
Else
Response.Write("Thispage requires Internet Explorer.")
End If
Response.Write(msg)
The Request.Browser property contains information aboutthe user s Web browser. In this example, searching for the string IE confirmsthe user is running Internet Explorer.
The Request.Browser.ClrVersion property contains detailedversion information for the most up-to-date version of the .NET Framework that sinstalled on the user s machine. The Major property will be zero if the userdoesn t have any version of the .NET Framework installed. The GetClrVersionsmethod (not shown) will return an array of all the versions of the .NET Frameworkthat are installed on the user s machine (in case you need such detailedinformation). In the vast majority of cases, that level of detail shouldn t benecessary, but it s nice to know it s there.
The Basics
To embed a custom Windows control in a Web page, you llneed an HTML snippet such as this:
A special technique is used to overload the ClassIDattribute so all the necessary information can be specified to launch the .NETcomponent. The ClassID must start with http: , which must be followed by thename of the DLL containing the .NET component. This DLL must reside in the Webapplication s root directory. After the DLL name there must be a pound sign (#),followed by the full name of the component (namespace included).
tags can be used to declaratively setproperties of the control. In the previous example, the BackColor property ofthe control is set to yellow. Client-side script can also be used to callproperties and methods of the custom .NET Windows control, as will be demonstratedlater in the article.
The unsupported browser text will only appear in caseswhere the message is true.
A Basic ComboBox
Using the technique just described, it s not possible torefer to any components that reside in the GAC, and, therefore, it s impossibleto refer directly to a standard Windows control. It is possible to use standardWindows controls in your Web pages, but they must be encapsulated within acustom assembly that can be referred to with the precise HTML syntax previouslylisted. It s not difficult.
For example, compile this simple class into a new WindowsControl Library using Visual Studio:
Public Class MyComboBox
InheritsSystem.Windows.Forms.ComboBox
End Class
Add the resulting control to a Web page using the earlierHTML snippet syntax and you re good to go. Don t forget to place the control sresulting DLL in the Web application s root directory, or else it won t bedownloaded to the user s computer.
An Enhanced ComboBox
A ComboBox isn t very useful unless you can get data intoand out of it. The above ComboBox control will be enhanced to retrieve its owndata from a Web service.
After setting a reference to a local Web service thatreturns a DataSet, this improved ComboBox control calls the Web service back onits home server and fills itself with the resulting data (see Figure 1).
Public Class ComboBox
InheritsSystem.Windows.Forms.ComboBox
Public Sub New()
MyBase.New()
'Fetch data from a webservice and fill the ComboBox
Dim ws As NewMyWebService.MyDataSource
For Each dr As DataRowIn ws.GetDataSet.Tables(0).Rows
Items.Add(dr(0).ToString)
Next
End Sub
End Class
Figure 1: Intendedto be hosted within a Web page, this customized Windows ComboBox controlretrieves its own data from a Web service.
This control inherits from the standard Windows FormsComboBox control, thereby getting all its functionality. It then extends thestandard functionality by calling a Web service from within the constructor. Finally,it loops through the records and adds them to the Items collection of theComboBox. Figure 2 shows it in action.
Figure 2: Don t be discouraged bythe fact that there s no ComboBox Web control in ASP.NET. The Windows FormsComboBox control can be used in Web applications.
To retrieve the value the user selects in the ComboBox, anOnSubmit attribute is added to the HTML Form tag. Using a line of JavaScript,the ComboBox value is placed into an HTML HiddenTextBox control just before thepage is submitted back to the server:
onsubmit="document.forms[0].HiddenTextBox1.value =
document.forms[0].ComboBox1.Text;"
Because that HiddenTextBox is marked with the runat= Server attribute, the value can be easily retrieved from server-side code:
Response.Write("You chose " + HiddenTextBox1.Value)
An Animated Bar Graph Control
The bar graph shown in Figure 3 is another example of acustom Windows Forms control that doesn t need to post back to the server. Infact, there is no server-side code needed at all for this page, as you can seeby the plain HTML page listed in Figure 4.
Figure 3: It would be difficult ifnot impossible to implement such a rich, animated bar graph as this with HTMLand JavaScript alone. Windows Forms controls are simply better at many tasksthan Web controls.
classid="http:ControlFreak.dll#ControlFreak.BarGraph" name="WinWebBarGraph1" VIEWASTEXT>
September: name="txtSep">
October: name="txtOct">
November: name="txtNov">
December: name="txtDec">
name="graphbutton" type="button" value="Button">Static name="graphbutton" type="button" value="Button">RandomAnimation name="graphbutton"type="button" value="Button">SmoothAnimation WinWebBarGraph1.AddBar("September",40); WinWebBarGraph1.AddBar("October",50); WinWebBarGraph1.AddBar("November",60); WinWebBarGraph1.AddBar("December",70); WinWebBarGraph1.DrawBarsAnimatedSmooth() function graphbutton_onclick(AnimStyle) { WinWebBarGraph1.ClearBars(); WinWebBarGraph1.AddBar("September",txtSep.value); WinWebBarGraph1.AddBar("October",txtOct.value); WinWebBarGraph1.AddBar("November",txtNov.value); WinWebBarGraph1.AddBar("December",txtDec.value); if (AnimStyle==1)WinWebBarGraph1.DrawBars(); if (AnimStyle==2)WinWebBarGraph1.DrawBarsAnimatedRandom(); if (AnimStyle==3)WinWebBarGraph1.DrawBarsAnimatedSmooth()} Figure 4: Windowscontrols can be embedded in plain HTML pages, with no server-side required. Inthis example, client-side JavaScript is used to call methods of the Windowscontrol that are hosted within the browser. Just after the beginning tag you can see the The final graphbutton_onclick JavaScript function operatessimilarly when one of the buttons is clicked, setting the bar graph values tomatch the user s input. The bar graph control is capable of two different kindsof animation, as well as a static (non-animated) layout. There is an HTMLbutton on the form matching each animation style. All three buttons call this client-sideJavaScript function, which clears the old bar values, adds new bars with sizesthat match the user-entered values, and sets the animation style according tothe user s command. Internally, the BarGraph control contains a collection ofBar objects. The Bar class is nothing very fancy; basically, it s just acontainer to hold a few values. The Bar class is defined in Figure 5. Public Class cBar Public Sub New(ByValText As String, _ ByVal Value AsDouble) _text = Text _Value = Value End Sub Dim _text As String =String.Empty Public Property Text()As String Get Return _text End Get Set(ByVal Value AsString) _text = Value End Set End Property Dim _Value As Double = 0 Public Property Value()As Double Get Return _Value End Get Set(ByVal Val AsDouble) _Value = Val End Set End PropertyEnd ClassFigure 5: A barobject is instantiated for each bar in the BarGraph control. What s more interesting is the code for the actualBarGraph control. The basic drawing method for this control is listed in Figure6. This function is for drawing the static (non-animated) version of theBarGraph control. Public Sub DrawBars() Timer1.Enabled = False 'initialize a drawingsurface Dim objBitmap As Bitmap =New Bitmap(Me.Width, Me.Height) Dim objGraphics AsGraphics = _ Graphics.FromImage(objBitmap) objGraphics.FillRectangle(New SolidBrush(Me.BackColor), _ 0, 0, Me.Width,Me.Height) 'loop through and draweach bar Dim iCount As Integer = 0 For Each Bar As cBar In_Bars 'determine the bardimensions Dim Width As Single =_ Convert.ToSingle(Me.Width / _Bars.Count - 20) Dim BarHeightPercentAs Integer = _ Convert.ToInt32(Bar.Value / _Bars.MaxValue * 100) Dim BarHeight AsSingle = _ Convert.ToSingle(BarHeightPercent _ / 100 * Me.Height- 20) Dim rect As New RectangleF(iCount* Width + 20 _ * iCount + 10,(Me.Height - 10) - BarHeight, _ Width, BarHeight- 10) 'specify the barcolors Dim Color1 As Color =Color.Green Dim Color2 As Color =Color.Blue 'draw the bar objGraphics.FillRectangle(New _ Drawing2D.LinearGradientBrush(rect, Color1, Color2, _ Drawing2D.LinearGradientMode.ForwardDiagonal), rect) 'Draw the text Dim drawFont As NewFont("Arial Narrow", 10) Dim drawPoint As New PointF(rect.X,rect.Y + _ rect.Height + 1) Dim drawBrush As NewSolidBrush(Color.Black) objGraphics.DrawString(Bar.Text, drawFont, _ drawBrush,drawPoint) 'Draw the value drawPoint = NewPointF(rect.X, rect.Y - 14) objGraphics.DrawString(Bar.Value.ToString, _ drawFont,drawBrush, drawPoint) iCount += 1 Next Me.BackgroundImage =objBitmap _DisplayStyle =DisplayStyleEnum.NonAnimatedEnd SubFigure 6: TheDrawBars method of the BarGraph control loops through each bar and draws themalong with their associated text. First, the internal timer is disabled because it s usedonly for the animation functions. Then the drawing surface is initialized andis filled with the specified background color. The code then loops through eachBar object in the Bars collection. The bar dimensions are then calculated andthe two bar colors are chosen before each rectangular bar is drawn with agradient brush. The bar text is drawn just below the bar, and the bar value isdrawn just above the bar. Finally, the completed in-memory image is assigned to bethe background image of the control, which causes it to appear. Keep in mindthat all this code is being executed by the .NET Framework on the user smachine and the output is displayed in the user s browser. A similar function is shown in Figure 7. This function iscalled each time the encapsulated timer ticks, rapidly redrawing the bars withrandom colors and gradient modes. Public Sub DrawBarsAnimatedRandom() Dim rdm As Random = NewRandom 'initialize a drawingsurface Dim objBitmap As Bitmap =New Bitmap(Me.Width, Me.Height) Dim objGraphics AsGraphics = _ Graphics.FromImage(objBitmap) objGraphics.FillRectangle(New SolidBrush(Me.BackColor), _ 0, 0, Me.Width,Me.Height) 'loop through and draweach bar Dim iCount As Integer = 0 For Each Bar As cBar In_Bars 'determine the bardimensions Dim Width As Single =Convert.ToSingle(Me.Width / _ _Bars.Count - 20) Dim BarHeightPercent AsInteger = _ Convert.ToInt32(Bar.Value / _Bars.MaxValue * 100) Dim BarHeight As Single= _ Convert.ToSingle(BarHeightPercent / 100 _ * Me.Height - 20) Dim rect As NewRectangleF(iCount * Width + 20 _ * iCount + 10,(Me.Height - 10) - BarHeight, _ Width, BarHeight -10) 'determine the bar'scolors randomly Dim Color1 As Color =Color.FromArgb(rdm.Next(0, 255), _ rdm.Next(0, 255),rdm.Next(0, 255)) Dim Color2 As Color =Color.FromArgb(rdm.Next(0, 255), _ rdm.Next(0, 255),rdm.Next(0, 255)) 'random gradient style Dim ldb AsDrawing2D.LinearGradientMode Select Case rdm.Next(0,3) Case 0 ldb=Drawing2D.LinearGradientMode.BackwardDiagonal Case 1 ldb =Drawing2D.LinearGradientMode.ForwardDiagonal Case 2 ldb =Drawing2D.LinearGradientMode.Horizontal Case 3 ldb =Drawing2D.LinearGradientMode.Vertical End Select 'draw the bar objGraphics.FillRectangle(New _ Drawing2D.LinearGradientBrush(rect,_ Color1, Color2,ldb), rect) 'Draw the text Dim drawFont As NewFont("Arial Narrow", 10) Dim drawPoint As NewPointF(rect.X, rect.Y + _ rect.Height + 1) Dim drawBrush As NewSolidBrush(Color.Black) objGraphics.DrawString(Bar.Text, drawFont, _ drawBrush,drawPoint) 'Draw the value drawPoint = NewPointF(rect.X, rect.Y - 14) objGraphics.DrawString(Bar.Value.ToString, _ drawFont,drawBrush, drawPoint) iCount += 1 Next Me.BackgroundImage =objBitmap _DisplayStyle =DisplayStyleEnum.AnimatedRandom Timer1.Enabled = TrueEnd SubFigure 7: TheSystem.Random class is used extensively in this alternate version of theDrawBars method to create an alluring animation of random, pulsating colors. The general structure of this method is essentially thesame as the DrawBars method. It starts by initializing a drawing surface andfilling it with the specified background color. Looping through each bar, thesame calculations are used to determine the bar dimensions. Then things startto diverge a bit. A random gradient mode is chosen; the gradient colors arechosen randomly, as well. Then, as in the DrawBars function, the text valuesare drawn and the function finishes by assigning the image to be the backgroundimage of the control. A client-side timer is enabled, ensuring that thisfunction will be called again shortly so that the next frame of the animationcan be drawn. The full source code for the BarGraph control containsanother function named DrawBarsAnimatedSmooth (the full source code isavailable; see end of article for download details). This function is similar,but uses slightly different randomization algorithms for the drawing to createan alternate (but equally alluring) animation. Limitations and Security Issues Windows Forms controls are better than ActiveX controlsfrom a security standpoint. Every Web-based ActiveX control comes with asecurity warning that users must accept or deny no matter what the controldoes. The control might be entirely harmless or it might maliciously reformattheir hard drive. It s an all-or-nothing scenario, and if an uneducated usermakes the wrong choice, there is no limit to the potential negative outcomes. Today,ActiveX controls are one of the primary sources of Spyware and Adwareinfections. The .NET Framework provides a much more robust securitysystem, improving upon Java s Sandbox methodology. To make decisions aboutwhether the control is harmless or potentially dangerous it examines the kindsof functions that the control wants to use, evidence about the user, andapplication context. Potentially dangerous functions are blocked fromexecution, although educated users can make exceptions with the .NET FrameworkWizard located under Control Panel | Administrative Tools. The controls in this article contain no potentiallydangerous function calls; therefore, they are automatically downloaded and runon the user s computer without any kind of warning or dialog box needing toappear at all. What kinds of functions are considered potentiallydangerous? Internet-based applications have the most restrictions, while intranetapplications have somewhat more lenient boundaries. For example, all networkcalls are blocked for Internet applications except calls back to theoriginating application. The ComboBox control listed earlier in this articlecalls back to the same server from which the containing Web page is hosted. Callsto a different server would fail unless the user (or a custom installationprogram) explicitly grants the assembly the necessary permissions. Thissecurity is based on the URL, so http://localhost is considered different thanhttp://192.168.0.1 even if both those URLs ultimately point to the sameserver. If you tinker with the ComboBox control from this article, make surethe browser s URL root matches the URL root of the Web service it is calling. Access to the user s hard drive is also heavilyrestricted. Although isolated storage is available for temporary files, readingfrom other locations is strictly prohibited unless the user explicitly choosesa file through the permitted OpenFileDialog class. Reflection and Serialization are also entirely prohibited.No XSL transformations are permitted, and ADO.NET access is limited. Calls tounmanaged code are prohibited, such as Windows API functions. Another issue is that communication between client-sidescript and Windows controls is currently one-way only. That is, JavaScriptfunctions within the page can call methods of the hosted Windows control, butthe Windows control cannot raise events back to the page. This (hopefullytemporarily) broken functionality is related to the current mix of patches forWindows, Internet Explorer, and the .NET Framework. Although this limitation isannoying, you should be familiar with such one-way communication because it isessentially a metaphor for HTTP communication. That is, Web browsers can makerequests to Web servers, but Web servers cannot call directly to a Web browserwithout the Web browser initiating the conversation. Unfortunately, all of these limitations rule out a lot ofpotentially useful applications, but most of these limitations are there forgood reason so users can sleep more soundly at night (and so Microsoft won tcatch so much heat about security problems!). Despite the limitations, clearly there are many good usesfor Windows Forms controls in Web applications, just a few of which have beendemonstrated in this article. C# and VB.NET samplecode accompanying this article is available for download. Steve C. Orr is anMCSD and a Microsoft MVP in ASP.NET. He s been developing software solutionsfor leading companies in the Seattle area for more than adecade. When he s not busy designing software systems or writing about them, hecan often be found loitering at local user groups and habitually lurking in theASP.NET newsgroup. Find out more about him at http://SteveOrr.net or e-mail him at mailto:[email protected].
About the Author
You May Also Like