Monday, January 09, 2006
Data Binding in Windows Forms 2.0 - by Brian Noyes

This meeting will be on Tue, Jan 17, 206 at 6pm. Location: Sarasota Community Foundation, located at 2635 Fruitville Rd., Sarasota, FL 34237 (just west of Tuttle on the north side of Fruitville).

Windows Forms 2.0 introduces a host of new capabilities for managing data binding scenarios. The BindingSources component allows you to easily bind to almost any kind of data source, and the Data Sources window in Visual Studio 2005 makes it easy to generate the code to hook up BindingSources to controls. This session will demonstrate the use of BindingSources and the Data Sources window to handle a variety of complex data binding scenarios including Master-Details, data bound custom controls, and keeping multiple sets of data bound controls synchronized.

About Brian Noyes:

Brian Noyes is a Microsoft MVP and an international speaker, trainer, writer and consultant with IDesign (www.idesign.net). He speaks at Microsoft TechEd US, Europe, and Malaysia, Visual Studio Connections, SDC Netherlands, DevTeach Montreal, VSLive!, DevEssentials, and other conferences, and is a top rated speaker on the INETA Speakers Bureau. He has published numerous articles on .NET development for MSDN Magazine, CoDe Magazine, The Server Side .NET, and other publications. Brian latest book, Data Binding with Windows Forms 2.0, part of the Addison-Wesley .NET Development Series, will hit the shelves in the January 2006, and his next book, Smart Client Deployment with ClickOnce will follow in the summer of 2006. Brian’s blog can be found at http://www.softinsight.com/bnoyes/.

Please be sure to register on our website in order to get updated information about all meetings and any other up coming events in the Sarasota area. Also if you are interested in sponsoring our little but growing local developer community please e-mail me.

1/9/2006 6:24 PM Eastern Standard Time  #    Disclaimer  |   | 
 Saturday, January 07, 2006

Today I was looking forward to seeing Bill Gates keynote address that he gave at the latest CES in Las Vegas. I went to Bill Gates webcast website and clicked on the 300K streaming media link as I have a very high speed internet connection. However, to my disappointment the webcast ended up not a fluid dynamic presentation but rather more of an audio show with still images taken from the webcast. So this begs the question as to why is it that Microsoft can not seem to get streaming media correct?

 

I contrast this with the same keynote experience from Steve Jobs using Apple’s Quicktime media player. What did I see a fluid, crystal clear experience of the presentation with just some minor stuttering and glitches as one would expect even from a high speed connection.

 

Now you see I am using a brand new Dell Windows Media Center edition PC with one of the best video cards available and one of the highest speed processor that I can buy. Why is it that on a Windows machine the streaming media experience is so much better with Quicktime than with the Windows Media player? It is pure shameful that this should be the case. How can Apple develop so much better of a Windows program than Microsoft?

 

I would love to see the Bill Gates keynote but I am simply spoiled the sheer quality of the Quicktime experience. I eventually gave up viewing the keynote using the streaming media using the Windows Media player. Hopefully the developers at the Windows Media center are listening and working hard to solve this issue with the program. Because if they do not hurry up Apple will quickly overtake them with the home entertainment experience. Just my little rant for the day I guess.

1/7/2006 2:32 PM Eastern Standard Time  #    Disclaimer  |   | 
 Friday, January 06, 2006

For many developers out in the .Net community it was ASP.Net that initially drove them to switch from some other platform. This was most likely due to the much enhanced programming model that ASP.Net provided and the improvements in performance that were promised and delivered. However, although the ASP.Net platform is a highly robust and scalable system you should still be aware of a few tricks of the trade that may help you increase your performance on your web application.

 

During my years of working with .Net I have learned many things on how to properly deal with certain situations that arise. Hopefully, you will find this information useful.

 

Best Practice #1

It is usually a good idea to set the SmartNavigation property to true on most pages.

The reasoning:

This reduces or eliminates screen flickering during postbacks to the server. Furthermore the scroll position will be preserved.

 

Best Practice #2

Enable the ability for multiple postbacks when using AutoPostback controls by using a user interface device such as a button.

The reasoning:

If the user has disabled Javascript controls in their browser then there is no way for the user to submit the form unless you provide a button or other user interface device.

 

Best Practice #3

It is preferred to use the Server.HtmlEncode method when displaying data taken from the database to an HTML control or Web control.

The reasoning:

This makes sure that the special characters are displayed in the correct manner and prevents cross side scripting attacks.

 

Best Practice #4

It is always best to validate input on the client side by using a validator control. Also, make sure you also validate all data on the server side as well as unforeseen security vulnerabilities can put your server at risk.

The reasoning:

Validation of all data is a best practice in all situations. This ensures a consistent database and data integrity and the integrity of your website.


Best Practice #5

It is usually a best practice to make sure the client is still connected during a time consuming task. This can be accomplished using the Response.IsClientConnected method during a known time consuming task.

The reasoning:

This method allows you to check to see if the client is still connected to the server. If the client is no longer connected you can then use the Response.End method to end the session and free up resources.

 

Best Practices #6

It is usually a good practice to avoid the use of hidden fields in order to store data between page postbacks.

The reasoning:

There are few very good reasons for storing potentially sensitive information using hidden fields. These do not store data in an encrypted manner or can store any significant amounts of data.

 

Best Practice #7

It is usually a good practice to store data taken from either files or a database in the ASP.Net cache object if the data does not change much over a period of time and can be shared with multiple users on the webpage.

The reasoning:

By storing and caching the data taken from a file or database you increase the performance and scalability of your application.

 

Best Practice #8

It is a best practice to use a Global error handler in the Global.asax file of your application.

The reasoning:

This allows you to recover properly from unexpected exceptions in the current application. Also this may allow you to implement a common error recovery mechanism for your web application.

 

Best Practice #9

It is always best to never use the Off attribute when setting the <custom errors> attribute in the web.config file of your application when it resides on a production server viewable by the outside.

The reasoning:

Doing this will enable unauthorized visitors to view potentially sensitive information about your application thereby increasing the security risk that  your website can be attacked from outside visitors.


Best Practice #10

It is always best to set your application tracing in the web.config file rather than using the @Page directive on individual aspx pages.

The reasoning:

This allows you to enable application level tracing for the entire application rather than for each individual page of  your website.

1/6/2006 1:22 PM Eastern Standard Time  #    Disclaimer  |   | 
 Thursday, January 05, 2006

It can hardly be said that any serious programmer has had to deal with database programming at least some time in their careers. So it would be logical then to make sure your connection to these underlying databases are as efficient as possible. Hopefully I will share some of the best practices I have learned in dealing with ADO.Net programming. These techniques were learned from a variety of sources, many of them I can not remember sorry. Hopefully you will find them equally as useful as I do.

 

Best Practice #1

Always use native .Net data providers.

The reasoning:

It has been proven by using the native .Net data providers always perform better and allow you to take advantage of both the .Net framework and the full power of the underlying database.

 

Best Practice #2

Always use a config file to store your connection strings. Also it might be a good idea to encrypt these connection strings especially if stored in a dubious location.

The Reasoning:

It is always best to store data that might change in a location outside of your application where you can easily update the connection strings. Also encrypting the connection strings is always a good idea from a security standpoint.

 

Best Practice #3

It is always best to use Windows authentication mode when connecting to your SQL Server database, this really applies mostly to Windows Forms applications.

The Reasoning:

Windows authentication is always much safer as the username and password do not pass over the wire.

 

Best Practice #4

Always use an asynchronous delegate when establishing a connection from a Windows Forms application.

The Reasoning:

This will prevent the user interface from seeming to seizing up as the application attempts to connect to the underlying database.

 

Best Practice #5

Prefer to use the sorting methods on the SQL Server such as the ORDER BY, HAVING and GROUP BY statements.

The Reasoning:

By performing the sorting on the server side as opposed to the client side you save time because the server can perform the work faster.

 

Best Practice #6

You should always try to limit the number of rows in a resultset. This can be performed typically by using the TOP keyword or other similar methods.

The Reasoning:

By limiting the amount of information you send through the wire you make the application seem faster and this also allows for a more scaleable design.

 

Best Practice #7

It is always best to use the CommandBehavior.CloseConnection enumerated value when you invoke the ExecuteReader method of a Command object.

The reasoning:

This allows for better connection pooling as the connections that are opened are returned quickly.

 

Best Practice #8

It is always best to cancel before closing a DataReader object if you are finished reading any more rows.

The reasoning:

The close method of the DataReader class continues to read all remaining rows before it finally closes the object. This is a wasteful use of resources.

 

Best Practice #9

It is always best to use a parameterized command over dynamic SQL queries.

The reasoning:

This will improve performance and reduce the a SQL injection attack while also making your code much more easier to maintain.

 

Best Practice #10

It is always best to access tables through views and stored procedures over other methods like dynamic SQL queries.

The reasoning:

The stored procedures and views do not add any overhead to a SQL server while providing some level of indirection which allow you to change the structure of the database table without drastically affecting your client code.

 

Best Practice #11

It is always best to implement some sort of resultset pagination when dealing with results of 50 or more rows.

The reasoning:

Although not an easy task in most cases using this technique you can increase performance on both your server database and your client application as less overhead and network traffic is taking place at any one time.


Best Practice #12

It is always best to close a transaction as quickly as possible.

The reasoning:

When a transaction occurs one or more rows are locked which means other users or applications can not access them. By using as short of a transaction as possible you ensure the scalability and stability of your application.

 

Best Practice #13

Never rely on the default behavior of the DataAdapter object for managing concurrency issues with your database.

The reasoning:

The DataAdapter object relies on the underlying which will leave itself in an inconsistent state if an update occurs, this is because ADO.Net will only throw an exception and not resolve the actual conflict at hand.

 

Best Practice #14

It is usually best to implement a timestamp field when you are using optimistic concurrency.

The reasoning:

This will allow to more easily detect when another user has updated the database.

1/5/2006 7:55 PM Eastern Standard Time  #    Disclaimer  |   | 

SQL Server is a very powerful tool when used properly. It can also come to a screeching halt if left to rot with no maintenance and poor planning. While the program itself is highly scalable it is still subject to performance bottlenecks and slow response times caused by inattentive administrators and developers. I have learned much about SQL Server 2000 in the past year many of those are the best practices used by other developers and senior administrators. I hope to share that information with you now so that those just starting out can learn from what I have learned.

 

Best Practice #1

Download and install and actually use the SQL Server Best Practices Analyzer tool provided by Microsoft.

The Reasoning:

This tool will scan your databases for any code or implementation issues that do not conform to Microsoft Best Practices standards. This should be the starting point on any existing or currently in production database you may have. Now you can take each recommendation with a grain of salt as the tool is probably not aware of every situation a developer may face. So therefore it is always up to the developer or administrator to decide which practices to put into place.

 

Best Practice #2

Never start the name of any stored procedure with the SP prefix.

The reasoning:

All system stored procedures start with the SP prefix. Naming your stored procedures in this manner will cause potential clashes as service packs are released potentially with the exact same naming as your previous stored procedure. This is highly unwise.

 

Best Practice #3

Apply the latest service packs and security packs

The reasoning:

With so many potential threats against a database keeping your system up to date will ensure data integrity. Keeping data integrity should be the duty of anyone either developing on the database or administrating the database.

 

Best Practice #4

Keep your result sets that you return from your database as small as possible.

The Reasoning:

Not only does this greatly improve performance but it makes the database much more scalable and better able to handle more concurrent users.


Best Practice #5

Avoid the Insert statement when performing bulk inserts into your database.

The reasoning:

The DTS or BCP utilities are far better for inserting information in bulk into SQL Server. These utilities are far more flexible then the SQL Bulk Insert statements you may want to use.

 

Best Practice #6

Keep your stored procedures as small as possible.

The reasoning:

If two users are accessing the same stored procedure at the same time then two query plans will be stored in the cache. It is far better to have smaller stored procedures call other stored procedures then one very large stored procedure. This practice makes maintaining the code a bit easier as well.

 

Best Practice #7

Analyze all your query plans using the SQL Query Analyzer to make sure they are performing at optimum speed.

The reasoning:

Getting to know how to use the SQL Query Analyzer is one of the best things any serious developer can do to improve performance in an application. Using this tool you can see where are the bottlenecks in your code and thereby increase performance by altering indexes or even re-writing stored procedures.

 

Best Practice #8

Always code for multiple user scenarios

The Reasoning:

If  you plan ahead and design your database with the proper data concurrency issues already solved then the future up keep of your database will be minimized. While the upfront costs associated with this might be higher the potential payback can be great as a application changes in its lifecycle.

 

Best Practice #9

Use User Defined Functions wisely and sparsely.

The reasoning:

It is far better to use stored procedures in your code then User Defined Functions. While using these functions may at times increase the performance of  your database it is more likely that they will be converted into stored procedures in the future as the database matures.

 

Best Practice #10

Do not use Select * in your query design. Instead make sure you use the proper column names in the query.

The reasoning:

Using the proper column names decreases network traffic, takes less load on the database and hence can greatly improve performance.

Best Practice #11

Avoid the use of nullable columns.

The reasoning:

The use of the nullable column consumes an extra byte on each column used. Furthermore when querying data there is much more overhead with nullable columns. Try to use alternative methods when designing a database to allow for a representation of zero data in the column.

 

Best Practice #12

Analyze and avoid deadlocks at all costs.

The reasoning:

It is far better to access your data the same way each time you query  your database. Doing otherwise will create a deadlock situation when one process takes control while another process is fighting for the same control over the objects. This can greatly tie up resources and can cause your program to crash if not taken into account. Always try to avoid a deadlock before one occurs. Use hints on your queries to make sure they are performing the way you want them to.

 

Best Practice #13

Create indexes on highly selective columns.

The reasoning:

It is far better to create an index on a highly selective column as this will increase the performance of your database design.

 

Best Practice #14

Avoid using cursors or use cursors very wisely.

The reasoning:

Cursors consume far too much database resources to be considered a viable option in most cases. There are other options available and proper design of the program will account for this. However when you need to use cursors, when there is no other alternative, then use them very wisely and make sure  you research any issues with cursors before implementing them in production. Test the database under a realistic load scenario.

 

Best Practice #15

Always make sure your database is as normalized as possible.

The Reasoning:

This is database design 101 here folks. If you have an un-normalized database design make sure to normalize the database design to the 3rd normal form as this is considered to be the standard. The only excuse for a non normalized design is for performance reasons. However my argument with this should be that denormalizing a database schema should be considered a last resort.


Best Practice #16

Remember to SET_NOCOUNT_ON at the beginning of your SQL bataches, stored procedures, triggers, etc.

The reasoning:

Doing this will increase performance by reducing network traffic. Setting SET_NOCOUNT_ON suppresses the messages regarding how many rows are affected after executing INSERT,UPDATE, SELECT and DELETE statements.

 

Best Practice #17

Avoid the use of the TEXT and NTEXT datatypes in your database design.

The reasoning:

There are far too many issues associated with TEXT and NTEXT datatypes for them to be of any great use to you. Instead it is far better to use the varchar and char datatypes instead.

 

Best Practice #18

Do not store BLOBS in your database.

The reasoning:

A database was not designed to stored datafiles or images. Instead it is far better to store the location of these files inside the database and let the operating system handle the file I/O for you. This is far better way to store large data files in your database.

 

Best Practice #19

Always perform referential integrity checks and data validations using constraints such as the foreign key and check constraints.

The reasoning:

It is far better to use constraints as opposed to triggers when performing referential integrity checks. The use of triggers should only be used to perform custom data validation that can not be performed using constraints.

 

Best Practice #20

Make sure all your stored procedures return a value indicating their status.

The reasoning:

Make sure you standardize on the return types your stored procedures should return indicating either success or failure. Doing this will increase the maintainability of the code and make programming against it much easier. This is especially ture if everyone understands and follows the standards.

 

Best Practice #21

Make sure you start each clause of your SQL statement on a new line.

The reasoning:

This makes the SQL code much more readable. You should consider this especially if you are in a team environment or a visiting consultant.


Best Practice #22

It is always best to avoid the use of column numbers in the ORDER BY clause.

The Reasoning:

Using some column numbers does not increase the performance of your query by any significant amount and also this makes  your code harder to read especially in large queries.

1/5/2006 4:24 PM Eastern Standard Time  #    Disclaimer  |   | 

Stings are a difficult and sometimes touchy subject when it comes to programming. In the C language improper use of strings can crash your whole system. Even some professors in Colleges and Universities do not teach their students how the native string functions in the C language work simply because they consider them far too dangerous for students to learn.

 

I will try to cover the best practices of handling strings that I have picked up over the years in the hope that it will either improve your performance or stop you from making some of the blunders I have made in the past.

 

Best Practice #1

Pertains to Visual Basic

It is always best to use the & to concatenate strings instead of the + operator.

The reasoning:

The + operator was only kept for historical reasons. It is far better to use the & operator because it make your code easier for other programmers to read it.

 

Best Practice #2

Use a char variable instead of a string variable only if you are certain you need to store only one character.

The reasoning:

The char variable takes up less space than a 1 character string.

 

Best Practice #3

Always explicitly initialize string variables to a zero length string.

The reasoning:

By explicitly initializing a string variable you avoid NullReferenceException errors when you reference the string.

 

Best Practice #4

You should always return an empty string when defining a method or property when the end result string has no characters.

The reasoning:

This simplifies the task of the calling code which will then not have to test for a null.

 

Best Practice #5

Never use language specific string functions.

The reasoning:

Language specific functions always perform worse their .Net native methods.


 

Best Practice #6

When checking for empty strings compare the length property with zero rather than with a String.Empty

The reasoning:

Checking the string length for zero has better performance then with the String.Empty method.

 

Best Practice #7

When comparing two strings use the String.Compare method to compare strings in case insensitive mode.

The reasoning:

The ToUpper and ToLower methods both create a new string and by doing this affect the memory heap. Also the Compare static method is far faster then using the ToUpper and ToLower string functions because there is no need to create new strings and then compare them.

 

Best Practice #8

Always use the Regex type to validate string input by the user or read from an external source such as the file system.

The Reasoning:

You should always validate input from any source that could affect the security or performance of your application.

 

Best Practice #9

Never hard code any value or variable that may change once the application goes into production. Instead store those values in a config file that your program can use to update those values dynamically.

The reasoning:

You simply do not want to have to update the entire program simply because something has changed in the production environment. This is a headache you simply want to avoid at all costs.

 

Best Practice #10

Avoid hard coded strings that may appear in the user interface. Instead use a resource file instead.

The reasoning:

You always want to avoid any programming that would make it difficult in the future to update your application.

1/5/2006 1:08 PM Eastern Standard Time  #    Disclaimer  |   | 

It is highly likely that in a certain amount of time of programming you will run into the term Object Relational Mapping. So what is Object Relational Mapping exactly? Object relational mapping is the technique of linking a relational database to a set of objects. There is no one to one relationship between object oriented programming and relational databases, this is called a impedance mismatch in the industry.

 

You see a relational database contains the normalized data structure of a particular entity or series of entities. For instance a “address object” contains information such as house number, street, city and state and zip code that is stored in an underlying database that persists the information for later retrieval. However according to normalization rules this data is stored in a non object oriented format. Object relational mapping attempts to solve the problem by mapping the entities in the relational database with those corresponding objects.

 

Fortunately this problem is well known and can be solved through many free and open source object relational mapping tools. Each program attempts to implement a variation on a particular theme. For instance there seems to be two schools of thought on the matter, a Entity (Chen/Yourdon) approach or a Domain (Fowler/Evans) model approach. Whether you subscribe to one model or the other will depend on which tool you prefer to use.

 

Since I am mostly interested in .Net oriented approaches I am only going to list those open source object relational mapping tools on this blog. This is not to say that the other languages do not have equally adequate tools in fact many of the .Net tools are based upon previous languages own implementations of the tool. Now keep in mind that some of these tools may be open source but not free.

 

Here is just a brief listing of some of the open source object relational mapping tools that I am aware of today.

 

Retina.Net

AtomsFramework

Gentile.Net

iBatis.Net

NHibernate

Neo

NPersist

OJB.Net

LLBGenPro

 

Hopefully you now have a better understanding of Object Relational Mapping and the why this is such a problem and the tools you can use to solve this problem. I know I have really only scratched the surface of the subject here but I do play on writing more about this subject as it is one that interests me.

1/5/2006 10:00 AM Eastern Standard Time  #    Disclaimer  |   | 
 Wednesday, January 04, 2006

Published by: Apress

Author: Eric White

 

Introduction:

 

It is stated in this book that this book is for developers who wish to enhance their programming skills in order to create custom controls. The primary language for this book is C#, this is most likely just a personal preference by the author of the book and it should not really adversely affect any other developer who writes code in other languages. Basically the techniques in this book can be applied by any Visual Basic .Net developer or even an Visual C++ .Net developer. The approach the author chose to take is to first give a brief introduction of what GDI+ actually is and then dive into the nuts and bolts of the underlying framework of GDI+ and then finally go into the architecture and development of Windows custom controls.

 

It is important to note that the source code for this book is available online at the APress website. You must download the code yourself if you want to see examples the coincide with each chapter of the book.

 

You can download the source code here:

 

Chapter 1: .Net Graphics Programming

This chapter provides a good introduction of .Net graphics programming. All the necessary topics are covered for even the most novice programmer. The highlight of this chapter is the overview of the namespaces of GDI+ programming which are listed in the table below.

 

Namespaces

Description

System.Drawing

This namespace is where all the basic graphics functionality. This includes the drawing surfaces, images, colors, brushes, pens and fonts.

System.Drawing.Drawing2D

This is where the raster and vector graphics functionality is located in the GDI+ namespace.

System.Drawing.Imaging

This is where the advanced imaging functionality is located which is an extension of the System.Drawing namespace.

System.Drawing.Printing

This is where the printing and print preview functionality of the framework resides.

System.Drawing.Text

This is where the advanced font functionality is located.

System.Drawing

This is where the advanced design time support of custom controls.

 

An overview of the basic of custom controls is also covered in this chapter quite well.

 

Chapter 2: Drawing Surfaces

This chapter covers what to consider when drawing to specific target environments. These target environments are a window on a screen (known as a form), a page (sent to a printer) and an image (such as a bitmap) since these all can be drawn to by pixels it is important to note the differences between these drawing surfaces simply because not doing so can affect your program in a very negative manner. I have personal experience debugging a C++ program that had its share of pagination issues and I have to note that many of those issues were most likely caused by the poor translation from one drawing surface to another.

 

The author does a fairly good job in explaining how to deal with each target environment. However as this is an early chapter some points are purposely left to other chapters to fill in. As there is a complete chapter printing it is wise to reason that the more in depth discussion of that drawing surface would be covered in more detail in that chapter.

 

Chapter 3: Pens and brushes

This chapter builds on the previous one in that it describes how to actually draw images on the screen using pens and brushes. Pretty much every aspect of the task of using pens and brushes is covered exhaustively in this chapter. Also, when covering this topic the author makes sure you understand how these methods are interacting with the screen, printer, etc to make absolutely sure you take all considerations into effect before setting down and using this namespace.

 

Chapter 4: Text and fonts

This chapter is perhaps the most drawn out text on fonts and text I have ever seen. Now this is not necessarily a bad thing as without text no information can be conveyed to the end user. Furthermore, the first GUI interface main attraction was the use of the fonts only seen in well published novels and magazines. Again every aspect of the namespaces that control how and where text is laid out on the screen or printer is covered very well in this chapter.

 

Chapter 5: Images

The use and manipulation of images is covered exhaustively in this chapter. However I would not use this chapter as a sole resource on the subject of image manipulation. Rather I would turn my eye to the open source projects that do the same thing but in an actual application. This would be something like the open source project Paint .Net. You can use this chapter to get a better understanding of what is going on in the underlying code in the project but since the examples are rudimentary and elemental at best it is far better to see this code in an end product such as Paint .Net.

 

Chapter 6: Graphics Paths and Regions

Now this chapter was interesting as it covered regions which can be used by Windows Forms as a way to create a more customized user interface and hence user experience. Again, an exhaustive coverage of the material is covered. With this understanding hopefully you will have the knowledge to better manipulate the regions and graphic paths in your programs.

 

Chapter 7: Clipping and Invalidation

Not a whole lot to say about this chapter except that the same exhaustive coverage of the material is continued with this chapter.

 

Chapter 8: Transformations

Again not a whole lot to say about this chapter except for the same exhaustive coverage of the material is continued again with this chapter.

 

Chapter 9: Printing

This was a special chapter for me as I worked on a project in my senior year at college that dealt with issues on pagination in a visio like program. Some of the same techniques I employed to debug the program were illustrated in this chapter. Ofcourse I was using MFC at the time and did not have access to the .Net framework but the techniques employed here would apply to many languages.

 

Chapter 10: An alternative coordinate system

This chapter explains the authors use of his own coordinate system in order to solve issues he found while covering the previous material. Pretty much every method that you expect to see in the .Net 2.0 framework is repeated here but with the author’s own unique twist on things. I am unsure of the real benefits of this coordinate system as there really is no whiz bang examples that really make me believe that this is the way graphics programming should be done. Really this is my biggest complaint of the whole book is that the author does not really develop any really useful program that the reader would want to use in their everyday lives. Personally, I need to see how these coding techniques are put together in a real live program in order to maximize the benefit of the learning experience.

 

Chapter 11: Architecture and design of Windows Custom Controls.

Finally the meat of the book and it took 11 chapters to get to it! This is really disappointing. Not the content of this chapter by any means but the fact that it took 11 whole chapters to discuss what I believe is the main crux of the work, Windows Custom Controls.

 

Now while this chapter does employ simple examples to illustrate the point it is trying to convey I would love to see some meatier examples, perhaps in an extended appendix or online on the Apress website.

 

Chapter 12: Design time support

What is design time support? This is where the end user of your control has the ability to dynamically control the properties of your custom control. Since you are designing for another programmer you must consider all the ways to enhance the experience and increase the development time of the programmer. This chapter does a fine job explaining these techniques and through the simple examples the point is made clear.

 

Chapter 13: Scrolling

Now when I got to this chapter I thought, why devote an entire chapter to scrolling? After reading the chapter I was still left with that question. In the very beginning of the chapter the author explains that there is considerable amount of built in support in Windows Forms for scrolling. So why would you want to do it yourself since it has already been done? While this chapter does an excellent job of explaining how to implement this in your own custom controls I can only justify this chapter as a filler chapter.

 

Chapter 14: Mouse event and cursors

What is a graphical user interface without the mouse? Not much in my book. This chapter explains how to properly utilize this input device as it pertains to your custom control. Since this is the last chapter of the book I was expecting some sort of wrap up, however there was none. No really great words of wisdom from someone who develops custom controls on a daily basis, none of that. Somewhat disappointed.

 

Overall impression of the book

Now admittedly I am not a great graphics programmer by any means. However this book will certainly teach you the nuts and bolts of GDI+ programming. How that will benefit you is up to your own judgment.

 

Where this book needs improvement on is that fact that there is not one single project the reader can build upon in order to learn the concepts taught in this book. Also when the reader does get to the meat of the book the content is left hanging by excruciating examples that most readers will be able to find by doing a simple

 

 

Pro .NET 2.0 Graphics Programming
1/4/2006 7:46 PM Eastern Standard Time  #    Disclaimer  |   | 

Recently I have had the pleasure of using the open source content management system called DotNetNuke. I basically use this as my primary personal website as it is very easy to use and administer and does not mean I need to hand code HTML every time I wish to update my website. It also has the advantage of being editable from anywhere I have an internet connection.

 

This new version is a vast improvement over the previous version I was using which was version 1.0.10. Notably this version has an integrated scheduler provider which allows for tasks to be run in the background at designated intervals. Since this is an open source system you have the advantage of seeing how this code is implemented, such a bonus! The scheduler provider I believe should be implemented in every website I develop simply because this allows for hands free administration of some of the more mundane tasks of keeping a website as fast and efficient as possible. The creators of this content management system also included their architecture reasoning in the DNNDocs which can be located at the same place you can find the source code for this system.

 

The advantages of using DotNetNuke in its current form is its open source and hence free nature which allows experienced developers to extend and modify the existing code base to suit their needs. Some may want to use this as a base for an even larger web based application. Also, since this is one of the most popular open source projects on the internet today the community support is outstanding. Also since this demonstrates some of the best practices of developing an n-tier web application any serious web developer can obtain valuable nuggets of information and insight by studying the code and the reasoning behind those decisions.

 

However, when considering this for a large corporation such as one in the S&P 500 I would give some serious thought about the disadvantages to any open source system. An open source system appeals to the masses and this does not necessarily coincide with the specific business requirements of a large corporation. These requirements most likely would consider Sarbanes Oxley regulations, regulations by national state boards of oversight and local regulations that demand a high amount of information security that this portal may or may not satisfy. So therefore you have to consider the costs of implementing such improvements on this system or any open source system in order to meet those specific business requirements.

1/4/2006 4:24 PM Eastern Standard Time  #    Disclaimer  |   |&nb