Inking in ASP.NET 2.0, AJAX, and IE7 In the past year, new technologies from Microsoft have changed how we can add ink to Web sites and the change is definitely for the better! One small property added to ASP.NET 2.0 server controls, OnClientClick, has had a big impact on simplifying the process of moving ink from the Web page to the Web server. The capability that OnClientClick provides, allowing developers to tie both a client-side event and a server-side event to one Click event, was actually achievable prior to ASP.NET 2.0 using control attributes, but it was more complex to set up and not very discoverable. | " | Visual Studio 2005’s new UserControl TestContainer interface makes it much simpler to test and debug user controls.
| " |
Microsoft’s ASP.NET AJAX has removed the pain and the complex coding required to ensure that any ink in the control remained in place during a page postback. However, it does require a small change to how you build your control. In addition to these enhancements, there are three other points to be aware of. The first is the COM-Visible parameter for any ink controls that you will use in Web sites and the second is a change in Internet Explorer, which impacts how you embed the ink control into the Web page. Lastly, Microsoft Visual Studio® 2005’s new UserControl TestContainer interface makes it much simpler to test and debug User Controls. You no longer need to create a Windows Form just for this purpose. In this article, you will learn how to build a simple ink-enabled Windows Forms control that is ready to be placed in an ASP.NET page (with or without AJAX) and how to write ASP.NET 2.0 and AJAX-enabled Web pages that can host this ink control. Creating an Ink-Enabled Control When you create an ink-enabled Windows Forms control to use on a Web page, you need to consider two things that are different from a control that you’d place in a Windows Form. First, you won’t be able to debug the control from a Web site. Luckily, the new UserControl TestContainer in Visual Studio 2005 allows you to run and debug the user control while it is being designed. To test more complex functionality, you may want to embed the control in a simple Windows Form where you can debug from the Windows Form code into the user control as long as their projects are in the same solution. The second big difference is that your Web application cannot access the control’s methods from managed code. Why not? Because the user must download the embedded control to their computer, you will not be able to interact with the control from the server-side code, but only from client-side code-JavaScript. This means that you must try to embed as much of the control’s functionality and logic within the control and expose only the most minimal amount of functionality to the calling code (the JavaScript). For example, you’d place all functionality for the ink style (color, transparency, width) into the control. That way, you won’t have to write any JavaScript to attempt to deal with the colors. The only functionality that you should need to expose is anything that the page or Web application must control. For example, if the page of the Web application must have knowledge of the color that the ink uses, you would need to make a public property. As another example, suppose you need to persist the ink data. That would require having a public method that returns the ink data to the calling code. The page’s JavaScript function could call that method and have access to the ink data, and then pass it onto the server-side code, which could do something like store the data into a database. The ink control that I will create will have the following capabilities: - Draw in a variety of colors: black, blue, red, and green.
- Erase strokes.
- Inform the Web page of the current color that is being used.
- Expose the current ink data in the control.
- Load ink data into the control (with a special tweak for AJAX pages).
- Clear all ink from the control.
To create this control, start with a Windows Forms Control Library project, which will automatically create UserControl1. As with any Tablet PC development, you will need to start with the following actions: - Add the Microsoft.Ink API into the project references.
- Add an InkOverlay component to the control.
- Instantiate and enable the InkOverlay.
The control’s code should look like this when you have done these things: VB Imports Microsoft.Ink
Public Class UserControl1
Private inkO As InkOverlay
Private Sub UserControl1_Load(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load inkO = New InkOverlay(Me) inkO.Enabled = True End Sub
End Class
C# using Microsoft.Ink;
public partial class UserControl1 : UserControl { private InkOverlay inkO; public UserControl1() { InitializeComponent(); }
private void UserControl1_Load(object sender, EventArgs e) { inkO = new InkOverlay(this); inkO.Enabled = true; } }
In the control’s design surface, add some functionality for controlling the color. Drag a ToolStrip control onto the UserControl. You can create as many color buttons as you wish by clicking the button icon on the toolstrip. Figure 1 shows the four new buttons after changing the DisplayStyle to None and the BackColor to represent the desired colors.  Figure 1: The ink-enabled user control with the ToolStrip for affecting the properties of the pen.I added two more buttons, which both have the DisplayStyle property set to Text. The first button’s Text property is “Eraser” and the second is “Clean All”. The ink control will contain all of these functions. There’s no need to write any code in the Web page to control these actions. The buttons’ Click events will perform the following functionality: - The four color buttons will cause the ToolStripColorButtons_Click event to fire, changing the pen color to the background color of the clicked button.
- The eraser button will change the pen’s EditingMode to eraser. The default eraser mode is StrokeErase, which causes the entire stroke to be affected. Alternatively, you can change the InkOverlay’s EraserMode to PointErase if you prefer.
- The Clean All button cleans all ink from the entire control.
Note that if you are new to C# Windows Forms, you can wire up the Click event of each of the buttons to the following code in the Events portion of the control property window. All four color buttons will point to the btnColor_Click method. VB Private Sub btnColor_Click _ (ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles btnBlack.Click, _ btnBlue.Click, btnGreen.Click, btnRed.Click Dim btn As ToolStripButton = sender inkO.DefaultDrawingAttributes.Color = _ btn.BackColor 'make sure you are not in erase mode inkO.EditingMode = InkOverlayEditingMode.Ink End Sub
Private Sub btnEraser_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btnEraser.Click inkO.EditingMode = InkOverlayEditingMode.Delete End Sub
Private Sub btnClean_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btnClean.Click inkO.Ink.DeleteStrokes() Me.Invalidate() 'forces a redraw End Sub
C# private void btnColor_Click(object sender, EventArgs e) { ToolStripButton btn = ((ToolStripButton)sender); inkO.DefaultDrawingAttributes.Color = btn.BackColor; //make sure you are not in erase mode inkO.EditingMode = InkOverlayEditingMode.Ink; }
private void btnEraser_Click(object sender, EventArgs e) { inkO.EditingMode = InkOverlayEditingMode.Delete; }
private void btnClean_Click(object sender, EventArgs e) { inkO.Ink.DeleteStrokes(); this.Invalidate(); //forces a redraw }
The last three functions, shown in Listing 1, will be public so that the Web page’s client-side code can interact with the user control. The first returns the current color name, the second returns the ink data as a Base64-encoded string, and the third will load data into the control. This conversion to Base64 is critical for enabling the ink data to be transmitted over HTTP to get to the server-side code where you might do something such as store the data into a database, or in the case of this article, store it into a file. The LoadInkData_64 method has been written specifically to accommodate the control being placed in an AJAX page. On a normal page, any time the page posts back, the ink control would be re-instantiated. In that case, loading the ink data is simple. However if you are using AJAX and the page is only doing a partial postback where the ink control is NOT part of that postback, you’ll have to load ink into a control that may already have ink data in it. This code does that by disposing and then reinstantiating the InkOverlay. You can test the control by pressing F5 and invoking Visual Studio 2005’s UserControl TestContainer. As shown in Figure 2, you will find that the CurrentColor property is visible in the properties window and that you can use all of the functionality on the control’s surface. However, you cannot test the public methods here.  Figure 2: Running the UserControl project in Visual Studio 2005’s TestContainer.One last little design action to take is to set the control’s BorderStyle property to FixedSingle. This makes it easier to identify the boundaries of the control when you embed it into the Web form. Before building the project, it is necessary to change the assembly’s ComVisible attribute. You can do this through the project property pages by clicking the Assembly Information button on the Application tab and checking Make assembly COM-Visible. You can also change this attribute directly in the project’s AssemblyInfo file. This completes the ink object. Once you have created the Web site, you will need to copy the DLL from this compiled project into the Web site project. | & | | 
By: Julia Lerman Julie Lerman is a Microsoft MVP, .NET mentor and consultant who lives in the hills of Vermont. You can find Julie presenting on data access and other topics at user groups and conferences around the world. Julie blogs at thedatafarm.com/blog and is the author of the highly acclaimed Programming Entity Framework (O’Reilly Media). Follow Julie on twitter at julielermanvt.
jlerman@thedatafarm.com | Fast Facts | | ASP.NET 2.0 and AJAX have made building ink-enabled Web applications much simpler. This article will walk you through building your first ink-enabled control (specifically designed to be used in AJAX-enabled Web sites) and leveraging the new tools to get the control integrated with your Web site. You’ll also see how to prevent IE7 from spoiling the user’s inking experience. | |
Links
Workarounds for embedded object issue from Microsoft, “Activating ActiveX Controls” [http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp] Adobe‘s article, “Active Content Update Article” [http://www.adobe.com/devnet/activecontent/articles/devletter.html] |