Microsoft .NET is ringing in the next generation of application
development. .NET allows developers the freedom to mix and match new and
existing components while leveraging the diversity of programming languages
and tools available. However, if you are a programmer, you may find that you
need additional or enhanced functionality in the areas where .NET's
capabilities are limited. Fortunately, .NET is an open and extensible
platform. This extensible design has helped create a rich and diverse
ecosystem of independent component publishers (ICP) that provide a more
comprehensive platform and address areas from presentation layer design to
communication protocols and everywhere in between.
One area that exposes some limitations of the .NET Framework is imaging.
Examples of these limitations include 32 BitsPerPixelonly paint, limited
file format support, and limited functionality included with the PictureBox
control. However, just because these limitations exist does not mean that
you have to be limited by them. LEAD Technologies, Inc., an ICP producing a
series of components called LEADTOOLS for .NET, addresses these particular
shortcomings. With LEAD's controls you can overcome the limitations, and
extend the image support of .NET.
With LEADTOOLS, you can load images that are less than 32 BitsPerPixel,
and keep the data in its native format, thus reducing the amount of required
system resources (by up to 32 times for bitonal images). LEADTOOLS also
includes support for over 120 different image formats and subformats. In
contrast, .NET only includes native support for five file formats.
Additionally, LEADTOOLS extends the standard .NET PictureBox control by adding built-in zoom and scroll support, thereby eliminating
the need to write the code. All of the LEADTOOLS .NET classes can work with
the native .NET image classes as well as the LEAD Image class.
Listings 1 and 2 use both the native .NET classes and the LEADTOOLS .NET
classes to load and display a full-page 300-dpi bitonal image fit into a
rectangle. Listing 1 shows the .NET native code, while Listing 2 shows the LEADTOOLS version.
You will notice that the code is virtually identical to the standard
.NET source. By enhancing the .NET Framework while maintaining a similar
interface, ICPs allow tremendous technical and productivity gains with
minimum additional learning and effort for the developer.
The ability of components to extend the platform is something many VB
developers are familiar with, but now with the .NET Framework any developer
who writes in a .NET language can leverage the tremendous pool of components
in the market.
The additional power of .NET lies not just in its ability to allow all
developers, regardless of language choice, to take part in the benefits of
reusable components but rather in the ability for developers to inherit
from, extend, and enhance ICP components to meet their custom business
needs. A component's capability and quality is often defined by the relative
ease with which a developer can programmatically solve a business problem.
While at first glance a component might appear limited to a specific
business role, the reality is that for a component to be effective it must
be able to quickly deliver the business information efficiently to the end
user. This means that information must be presented in a useful manner while
limiting the amount of code the developer must create for
application-specific requirements.
Oftentimes a developer needs additional or enhanced functionality beyond
what is provided with the controls that ship with Visual Studio .NET. A
component from an ICP might meet 90% of the requirements but what about the
other 10%? In the past, developers have either created complex work-
arounds to fill in this hole or have spent tremendous time and resources
creating a component from the ground up in order to be able to add a small
amount of functionality not available on the market. The abstract nature of
the .NET Framework, with respect to architecture, enables components to
easily meet these challenges (see Figure 1). With the object-oriented
features of .NET you can inherit from the reusable component that best meets
your needs and only write the additional 10% that you need. Let's look at an
example.
If you wanted a true hierarchical grid to display customer order and
order details, you could use the ASP.NET grid from Infragistics. Part of the
Infragistics NetAdvantage Suite, the ASP.NET grid allows the rendering of
hierarchal data with ease. In addition the ASP.NET grid gives you additional
features such as Outlook Group By, multicolumn sorting, dynamic column
resizing, and extensive client-side support. However, what if you want to
apply a custom title or banner to span the top of the grid? This
functionality is not available in the ASP.NET grid from Infragistics but is
easy to add, thanks to the object-oriented design of the component and
features of the .NET Framework.
First you would create a new Web Control Library project. Then you would
set a reference to the Infragistics WebUI.Shared and WebUI.UltraWebGrid
libraries. You can download a trial version of the NetAdvantage Suite at
www.infragistics.com to obtain these libraries. Setting these references will allow you
to inherit from the controls.
Next, the control class is declared and set to inherit from the
Infragistics ASP.NET grid control. By inheriting from the Infragistics
control you will include all of the robust functionality provided natively
by the ASP.NET grid but will be able to add your own custom code.
<DefaultProperty("TitleText"), ToolboxData("<{0}:ExtendedDataGrid
runat=server></{0}:ExtendedDataGrid>")> Public Class ExtendedDataGrid
Inherits Infragistics.WebUI.UltraWebGrid.UltraWebGrid
For this example you'll want to add two basic properties, one, called
TitleText, to pass in the title of the grid and one, called TitleAlign, to
set the alignment of the text. Listing 3 shows a simple enumeration for the
TitleAlign property to restrict the users of the component so only the
correct values can be selected for alignment.
Now that the Infragistics ASP.NET grid control is extended to add the
custom TitleText and TitleAlign properties to the control it will need to
render the additional HTML to the output stream. Web controls produce most
of their HTML during the render event, so the new control will override the
event.
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
In this event the enhanced control will pick up the style properties
that the Web page developer has set on the base class's built-in header
section and use them for the new title section.
Me.DisplayLayout.HeaderStyleDefault.AddAttributesToRender(output)
After adding the style attributes the render event will set the width of
the new table to the width of the ASP.NET grid, which is fetched from the
base class, as shown in Listing 4. Then the correct HTML for an HTML table
is generated and the TitleText inserted. The event finishes by delegating
back to the base class to render the HTML for the control.
With just a few basic lines of code the .NET Framework allows you to
take an advanced and rich control, the Infragistics ASP.NET grid, and use it
as a solid foundation for your own custom control to meet your custom
business need. Adding this control to a Web page is no different than any
other control (see Figure 2). First you will need to register the control
with your page.
<%@ Register TagPrefix="cc1" Namespace="ExtendedDataGrid"
Assembly="ExtendedDataGrid" %>
After you have registered the control you can work with and set all of
the properties that you need either through code or the visual designers
(see Listing 5). To view the complete code for the extended Web control, see Listing 6 below.
Conclusion
Inheriting from and extending a control is not always enough, though.
Sometimes you need to extend a control at a lower level, such as adding
search functionality to a tree or adding client events. To prepare for these
possibilities you should look for a component vendor willing to supply the
source code for their product.
When you bring a component from an ICP into your application, you bring
in a partner in the success or failure of your application. Product source
code provides a level of security against unforeseen support issues and the
"black box" scenario that many developers choose to avoid. In addition,
having the source allows you to extend and customize a component to any need
you have, because the entire functionality is available for modification.
While Microsoft has ushered in the next generation in application
development with the .NET Framework, there are still areas that developers
will need additional resources to address. The ICP community has created a
robust set of components that allows you to work through these areas while
maximizing your productivity. However, when you have a specific and custom
need, the extensibility of the .NET Framework allows you to quickly and
easily extend a reusable component to meet the need while saving you from
having to spend valuable time and effort to create the code yourself (see
Figure 3).
Author Bio
Brad McCabe is a technology evangelist for .NET, ASP.NET, and .NET CF for
Infragistics (www.infragistics.com), a leader in providing a broad
infrastructure of reusable presentation-layer components essential for the
creation of next generation Web-based applications and XML Web services
utilizing .NET, COM, and Java.
brad@infragistics.com
Listing 1 .NET native code
Dim Img As System.Drawing.Image
Dim g As Graphics = Panel1.CreateGraphics()
Dim t1 As Date = Now()
Dim t2 As Date
Dim x As Integer
For x = 1 To 10
Img = System.Drawing.Image.FromFile
("d:\\images\ocr\ocr1.tif")
g.DrawImage(Img, 0, 0, Panel1.Width,
Panel1.Height)
Next x
t2 = Now()
MsgBox(t2.Subtract(t1).ToString())
g.Dispose()
Listing 2 LEADTOOLS code
Dim Img As LEAD.Drawing.Image
Dim g As Graphics = Panel1.CreateGraphics()
Dim t1 As Date = Now()
Dim t2 As Date
Dim x As Integer
For x = 1 To 10
Img = LEAD.Drawing.Image.FromFile
("d:\images\ocr\ocr1.tif")
Img.Draw(g, 0, 0, Panel1.Width,
Panel1.Height)
Next x
t2 = Now()
MsgBox(t2.Subtract(t1).ToString())
g.Dispose()
Listing 3 Adding custom properties
Public Enum TitleAlignEnum
Center = 0
Left = 1
Right = 2
End Enum
<Bindable(False), Category("Title"), DefaultValue("Center")>
Property TitleAlign() As TitleAlignEnum
Get
Return _titlealign
End Get
Set(ByVal Value As TitleAlignEnum)
_titlealign = Value
End Set
End Property
<Bindable(True), Category("Title"), DefaultValue("")> Property TitleText()
As String
Get
Return _titletext
End Get
Set(ByVal Value As String)
_titletext = Value
End Set
End Property
Listing 4 The render event
With output
Me.DisplayLayout.
HeaderStyleDefault.Add
AttributesToRender(output)
.AddAttribute("width", Me.Width.Value.ToString)
.RenderBeginTag("Table")
.RenderBeginTag("TR")
Select Case TitleAlign
Case TitleAlignEnum.Center
.AddAttribute("align", "Center")
Case TitleAlignEnum.Left
.AddAttribute("align", "Left")
Case TitleAlignEnum.Right
.AddAttribute("align", "Right")
End Select
.RenderBeginTag("TD")
.Write(TitleText)
.RenderEndTag()
.RenderEndTag()
.RenderEndTag()
MyBase.Render(output)
Listing 5 Setting properties for the control
<cc1:ExtendedDataGrid id="ExtendedDataGrid1" runat="server" Width="500px"
TitleText="Extending Controls is Easy With .Net" DataSource="<%# DataSet11
%>" DataMember="Orders" TitleAlign="Center">
<DisplayLayout RowSelectorsDefault="No" ColFootersVisibleDefault="Yes"
SelectTypeRowDefault="Single" ViewType="Hierarchical"
Name="ExtendedDataGrid1">
<HeaderStyleDefault BorderStyle="None" ForeColor="White"
BackColor="#6B6BB5"></HeaderStyleDefault>
<RowStyleDefault BorderWidth="2px" BorderColor="#FFFFFF"
BorderStyle="Solid" ForeColor="Black" BackColor="#C7C7D4"></RowStyleDefault>
<FrameStyle Width="500px" Cursor="Default" BorderWidth="0px"
BorderColor="#999999" BorderStyle="None"></FrameStyle>
<Pager AllowPaging="True" StyleMode="PrevNext"
Alignment="Left"></Pager>
<SelectedRowStyleDefault ForeColor="White"
BackColor="#7B7B9A"></SelectedRowStyleDefault>
<RowAlternateStyleDefault
BackColor="WhiteSmoke"></RowAlternateStyleDefault>
</DisplayLayout>
</cc1:ExtendedDataGrid>
Listing 6: Complete code for the extended Web control
Option Explicit On
Option Strict On
Imports System.ComponentModel
Imports System.Web.UI
<DefaultProperty("TitleText"), ToolboxData("<{0}:ExtendedDataGrid
runat=server></{0}:ExtendedDataGrid>")> Public Class ExtendedDataGrid
Inherits Infragistics.WebUI.UltraWebGrid.UltraWebGrid
Dim _titletext As String
Dim _titlealign As TitleAlignEnum
Public Enum TitleAlignEnum
Center = 0
Left = 1
Right = 2
End Enum
<Bindable(False), Category("Title"), DefaultValue("Center")>
Property TitleAlign() As TitleAlignEnum
Get
Return _titlealign
End Get
Set(ByVal Value As TitleAlignEnum)
_titlealign = Value
End Set
End Property
<Bindable(True), Category("Title"), DefaultValue("")> Property TitleText()
As String
Get
Return _titletext
End Get
Set(ByVal Value As String)
_titletext = Value
End Set
End Property
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
With output
' Get Header Style from the base control
Me.DisplayLayout.HeaderStyleDefault.AddAttributesToRender(output)
.AddAttribute("width", Me.Width.Value.ToString)
' Rener standard HTML table to output stream
.RenderBeginTag("Table")
.RenderBeginTag("TR")
' Align the text based on the TitleAlign enumeration
Select Case TitleAlign
Case TitleAlignEnum.Center
.AddAttribute("align", "Center")
Case TitleAlignEnum.Left
.AddAttribute("align", "Left")
Case TitleAlignEnum.Right
.AddAttribute("align", "Right")
End Select
.RenderBeginTag("TD")
.Write(TitleText)
' Close all the open HTML tags
.RenderEndTag()
.RenderEndTag()
.RenderEndTag()
' Call the base class's render event to stream out the controls
' HTML
MyBase.Render(output)
End With
End Sub
End Class
All Rights Reserved
Copyright © 2004 SYS-CON Media, Inc.
E-mail:
info@sys-con.com