Friday, September 28, 2007

Use of BeginUpdate() and EndUpdate() when populating ListView/TreeView

Often a listview control in C# needs to be populated with large amount of data (bulky operations, for example, adding 1000 items). For every item added in the Listview, the control will redraw itself, thus greatly reduce the overall performance.

However, using the two methods BeginUpdate() and EndUpdate() while performing these bulk operations gives significant advantage. A call to BeginUpdate() can be made before adding/deleting/clearing items. This will stop any paint messages being sent or processed. Once the operation is done, the EndUpdate() can then be called.


I have logged the time taken of the above code (i.e. adding 1000 items in a ListView for each button click) with and without the BeginUpdate/EndUpdate method calls using a test application.


The use BeginUpdate() and EndUpdate populates the control with a constant duration and much better performance. Amazing, isn't it?

Thursday, September 20, 2007

Write C# code for both full .NET Framework and .NET Compact Framework

Introduction
C# is fully supported on both the full .NET Framework and .NET Compact Framework and there are many times when a piece of code could have been used on both the "full framework" and "compact framework. A simple example would be the Business Logic as this would normally be the same in an enterprise project, whether the solution would be deployed on any of these platforms. I have attempted to write a simple application that addresses this issue, and I am sure there exist other ways to do this - google.com is a faithful friend :).

The Visual Studio Solution: FrameworkApps
There are three projects in the solution, and they are:

1. BusinessLogic, a class library project, that implements the business logic;
2. DesktopApp, a desktop application on the full .net framework platform;
3. DeviceApp, a device application on the .net compact framework platform.

The BusinessLogic.cs file is used by both the desktop and device application. Thus, any source files hould be added as links to the projects, to avoid duplicate source files.

Here is a snapshot of the project structure:



Conditional compilation
Conditional branching of the code at compile time is used to determine the code to be compiled during the compilation process. To achieve this, go to the desktop project properties and under the Build tab add a new "Conditional compilation symbol", say FULL_FRAMEWORK.



Implementation
Project: BusinessLogic
Source file: BusinessLogic.cs



Project: DesktopApp
Source file: Form.cs



Project: DeviceApp
Source file: Program.cs



Output
Set DesktopApp as the startup project and run the application:



Set DeviceApp as the startup project and run the application:



Hope it helps.

Monday, September 10, 2007

Automatic generation of XML Documentation in C# with GhostDoc

Writing XML comments while coding in C# can be a tedious task at times. By installing GhostDoc, a free Visual Studio add-in, you can automate this process and get some additional minutes to concentrate on the code :-)

What does GhostDoc do?
GhostDoc simply gives you a quick means of adding some comments to your classes/methods while you are using the editor to code in C#, by guessing a suitable (and meaningful) comments and thus, automates the process.

Note: GhostDoc assumes that the code follows Microsoft's Design Guidelines for Class Library Developers.

GhostDoc also includes options that allow you to modify existing rules and add additional rules that determine what kind of comments should be generated. Sounds exciting, isn't it?

What doesn't GhostDoc do?
GhostDoc doesn't do miracles...

GhostDoc is not a tool for creating the complete documentation for a given source file in one go. It can only document one member at a time, and you always have to check and, if necessary, correct the automated comments in order to meet match your preferred documentation.

Installation
Download it from http://www.roland-weigelt.de/ghostdoc/

Usage
While coding in the Visual Studio editor, right click on the class name, method, etc and select "Document this".


Give it a try!

Thursday, September 6, 2007

Millisecond component on .NET Compact Framework

One of the differences between full .NET Framework and .NET Compact Framework relates to the Time Intervals. The value returned from System.DateTime.Now is specific only to seconds, not milliseconds. Thus, the milliseconds component of the DateTime, usually expressed between 0 and 999 (in the full framework) will always be 0 on a compact framework platform.

Recommendation

Microsoft recommends the use of the TickCount property available in the Environment class in order to get a more precise time span measurement. This property returns the amount of time in milliseconds that has passed since the last time the computer was started.

http://msdn2.microsoft.com/en-us/library/system.environment.tickcount(vs.80).aspx

Hope it helps.

Monday, September 3, 2007

Optimal size of column headers in listview

When using a ListView in C# and the View property is set to View.Details, you probably want to set the width of the columns in the listview to an optimal size, without any … in the columns.

Problem
If the column text strings does not fit the column width (set at design time), three dots (...) will be displayed at run time, as shown below.



Aim
Display the text fully in the column, and get rid of the ...

Solutions??

For one moment, you may think of finding the length of the longest string in the column and assign it to the width of the column header. But wait, the length would be in terms of number of characters, whereas the width of the column should be in pixels. So, this will not work, unless you use a utility function to convert the length of the text (taking into consideration the font being used) and calculate it in terms of pixel. Yes it is possible :-) but you won't see it in this post!

Correct Solution
At runtime, set the Width of the ColumnHeader to:

a) -1 to adjust the width of the longest item in the column (without taking into consideration the column heading).

hdrCountry.Width = -1;
hdrName.Width = -1;



Now, the text in the columns is displayed correctly, but not the heading of the first column.

b) -2 to autosize width of the column, taking into consideration the column heading.


hdrCountry.Width = -2;
hdrName.Width = -2;



Now, it works fine. Hope it helps.