Sunday, December 14, 2008

Localizing .NET applications

Most applications nowadays have to be localized in order to provide user interfaces in the language of the user who uses the application. The .NET framework offers a very handy mechanism to provide localization for your apps. It uses so called resource files (.resx) to store keys and the corresponding translated texts or images. If you want to know more on how to work with this translation mechanism take a look at this post.
The main problem with these files is to keep them in sync (for example when adding new strings) and to give translators an easy tool to make translation without requiring them to have visual studio installed on their computers.
I found a tool called "ResEx ... the composite, translation friendly .NET Resource editor" which can be found here that meets exactly this requriements. It provides a nice spreadsheet interface which makes it also for non programmers easy to translate the resources in the files. It is also possible to group resources together by using an underscore e.g. Menu_Home, Menu_Customers; they will all be shown under the tree node "Menu" which makes it easier to understand where the translations are used. Even adding and deleting localization languages is very easy.
The only thing which is missing is to have an automatic translation by using one of the several online translators available nowadays. I will suggest it on the forum and maybe this feature will be available in a future release.

Another very useful tool when working with resource files is the Resoucre Refactoring Tool on CodePlex. It helps you by localize strings in your source code by putting the string into the resource file and replacing the corresponding call in order to get a translated string.

Generating script for SQL Server database

Recently I had to deploy a project which used a Microsoft SQL Server database. During the deployment process all the tables and some predefined data should be created in the database of the machine on which the application is installed. I needed a simple .sql file which contains SQL instructions to create the schema and to insert the data. I thought that this would not be a big deal because SQL Server Management Studio has many tools and functionalities and for sure also one to do this since it is an essential part of software deployment. I used the export Wizard and everything worked well except that with the Wizard it is only possible to export the schema. I was very surprised that it is not possible to export the schema and the data.
After some research on the internet I found several commercial tools which are able to export also the data but I did not want to purchase such a tool only to export the data.
I found that there is an "API" for the SQL Server which is called SQL Server Management Objects (SMO) and SQL Server Replication Objects (RMO). These two "API's" can be used to get information from an SQL Server such as all the databases, all the tables in a database and all other information related to an SQL Server. I played a bit with them and there exists a method for each server object (such as databases, tables,...) which is called Script(). This method returns a StringCollection which can be used to re-create the SQL object. It is worth to give a look if you have to create, update or delete SQL objects from within code.
I tried to build a tool which is able to export a whole database, all its objects (function, triggers,...) and the data to a single sql file. I faced several problems. First it is important in which order the tables and constraints are created because otherwise the script would not run successfully. Second I had to generate insert statements for the data which has to consider all datatypes supported by SQL Server.
In some way I would have been able to solve these two issues but then I found the Microsoft SQL Server Database Publishing Wizard 1.1. This tool by Microsoft does exactly what I need. It exports one or more databases with their schema, objects and the data. If you have a similar issue I suggest you to use this one since it is free and worked fine for me :-)

Here you can find the official home page of the publishing wizard tool on CodePlex.

Monday, December 1, 2008

Show Collection of strings in GridView

Today I faced the following problem; I had a collection of strings which I wanted to show in a GridView. I tried to use the collection as datasource, but nothing was displayed. A quick and simple solution to this problem is the following:
- First you add a template column to the grid view
- In the template for the item you create a Literal control
- Then the Text property of the Literal is set to DataItem of the Container which is evaluated when databinding occurs

This can be accomplished with the following code:
<asp:gridview id="GridView1" runat="server" autogeneratecolumns="False" onrowdeleting="GridView1_RowDeleting">
<columns>
<asp:templatefield headertext="column">
<itemtemplate>
<asp:literal runat="server" id="customerNames" text="<%# Container.DataItem %>"></asp:literal>
</itemtemplate>
</asp:templatefield>
<asp:commandfield showdeletebutton="True">
</asp:commandfield>
</columns>
</asp:gridview>

This code sets a string collection as datasource and binds it to the gridview:
List<string> list = new List<string>();
list.Add("Customer1");
list.Add("Customer2");
list.Add("Customer3");
list.Add("Customer4");
list.Add("Customer5");
list.Add("Customer6");

this.GridView1.DataSource = list;
this.GridView1.DataBind();

But now is the question: how con you retrieve the value for example in the RowDeleting event. As accustomed to windows forms I tried:
this.GridView1.Rows[e.RowIndex].Cells[0].Text;

but that did not work. To get the correct text I had to use:
((Literal)this.GridView1.Rows[e.RowIndex].Cells[0].Controls[1]).Text;

Alltogether the cell contains 3 controls. The other two are LiteralControls with the Text '\r\n ' and the second one is the Literal control which holds the text.

Tuesday, November 25, 2008

INSERT if new and UPDATE otherwise

Recently I faced the following problem. I had to insert a big number of records into a PostgreSQL database. I have created a string which contains the various insert statements like below. The primary key is defined on the columns a,b.

INSERT INTO tablename (a,b,c) VALUES (1,2,'abc');
INSERT INTO tablename (a,b,c) VALUES (2,2,'def');
INSERT INTO tablename (a,b,c) VALUES (2,2,'ghi'); --generates an error!!
INSERT INTO tablename (a,b,c) VALUES (3,2,'ghi');

This worked fine until I encountered a duplicate primary key violation. The main problem with this was that after the error, the transaction was aborted and rolled back. So no record was inserted. I wanted instead that if such an error occurs, the existing record gets simply updated with the new values and if no record exists, it should be inserted. I searched the internet and there where different proposals but none of them really convinced me. I then came up with the following function:

CREATE OR REPLACE FUNCTION insert_update_record(a_in int, b_in int, c_in character varying)
RETURNS void AS
$BODY$
BEGIN
-- try to insert the record
BEGIN
INSERT INTO tablename (a,b,c) VALUES (a_in, b_in, c_in);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- if there is a duplicate key exception
-- update the record
UPDATE tablename SET c = c_in WHERE a = a_in AND b = b_in;
END;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

This function simply tries to insert the new record into the table and if there is a duplicate key exception it will update the record. The previous insert statements would then be converted to:

SELECT insert_update_record(1,2,'abc');
SELECT insert_update_record(2,2,'def');
SELECT insert_update_record(2,2,'ghi'); --generates an error but does not abort the transaction
SELECT insert_update_record(3,2,'ghi');

I did not make any performance tests, but I believe that this function is not much slower than the INSERT statements if there are not many duplicates; because it simply makes an insert and returns and only if there is an exception it does some additional work. Since this function is precompiled it may be that it is even faster than the INSERT statement. Anyway the function can help you solve the insert/update problem.
Of course you have to adjust the function according to your needs, but if you have some experience with programming it shouldn't be too difficult ;-)

UPDATE:
Based on the suggestion of Peter I made up a new function which is pratically an implementation for PostgreSQL of his pseudo SQL statements:
UPDATE sample
SET testno = 1;
WHERE test = 'PL/SQL';
IF SQL%ROWCOUNT ==0
THEN
/* Insert Statement */

END IF;

I have created then a table 'test' with the columns 'id' (pk), 'val1' and 'val2'. Then I converted the pseudo SQL into:

CREATE OR REPLACE FUNCTION update_insert(id_in integer, val1_in integer, val2_in integer)
RETURNS void AS
$BODY$
DECLARE
count int;
BEGIN
update test set val1 = val1_in, val2 = val2_in where id = id_in;
GET DIAGNOSTICS count = ROW_COUNT;

IF count = 0 THEN
INSERT INTO test (id, val1, val2) VALUES (id_in, val1_in, val2_in);
END IF;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

and provided also the function for this table with the exception handling:

CREATE OR REPLACE FUNCTION insert_update(id_in integer, val1_in integer, val2_in integer)
RETURNS void AS
$BODY$
BEGIN
-- try to insert the record
BEGIN
INSERT INTO test (id,val1,val2) VALUES (id_in, val1_in, val2_in);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- if there is a duplicate key exception
-- update the record
UPDATE test SET val1 = val1_in, val2 = val2_in WHERE id = id_in;
END;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

Then I created with a small application the SQL statements that call these functions and I created them with differenct percentage of duplicates:

SELECT insert_update(1,101,-99);
and
SELECT update_insert(1,101,-99);

Here are the results of my performance measures:
1 000 statements
tried to insert every id twice -> 500 records in DB
update_insert: 250ms
insert_update: 250ms

100 000 statements
tried to insert every id twice -> 50 000 records in DB
update_insert: 37281ms
insert_update: 45125ms

100 000
every 10th record was already present -> 90 000 records in DB
update_insert: 63875ms
insert_update: 61500ms

10 000
all ids were the same -> 1 record in DB
update_insert 10016ms
insert_update 18703ms

I did the tests on my laptop; I know that they may not be precise because of running services in the background, but at least they give an intuition.
The result of my test:
- High number of duplicates -> the update/insert function is much faster
- Low number of duplicates -> the two functions are almost equally fast

I was surprised that there is not more difference between these two functions. I expected that the function with the exception would be much slower than the other one. I would suggest to use the update/insert function as proposed by Peter because exceptions should only be used in exceptional situations and avoided when possible.
Thanks Peter for the proposal...

Saturday, October 18, 2008

Extension Methods in C#

There are some new features in C# 3 which are introduced to make LINQ possible.
One of them are extension methods which I wanted to try out. Extension methods are static methods which can be applied to any object type which is specified as "special parameter". For example if you want to extend the type string with the method "Greet" you write something like this:
public static void Greet(this String s)
{
Console.WriteLine("Hello " + s);
}


Then you can call it like:
string name = "Tom";
name.Greet();


This will produce the following on the console: "Hello Tom"

I played a bit with this extension mehtods and came up with the following extensions for object which I believe can be helpful.
Assume the following object:
Customer testCustomer = new Customer() { Name = "John", Age = 35, LastName = "Smith" };


PrintConsole() -> prints the string representation of an object to the console
Code:
testCustomer.PrintConsole();

Produces:
"ExtensionMethodTest.Customer"

PrintMessageBox() -> shows the string representation of an object in a message box
Code:
testCustomer.PrintMessageBox();

Produces:


PrintPropertiesConsole() -> Prints all public non inherited properties and their values of the object to the console
Code:
testCustomer.PrintPropertiesConsole();

Produces:
Properties of 'ExtensionMethodTest.Customer'
Name: John
LastName: Smith
Age: 35

PrintPropertiesMessageBox() -> Shows all public non inherited properties and their values of the object in a message box
Code:
testCustomer.PrintPropertiesMessageBox();

Produces:

string ToXml() -> Serializes the object to XML and returns the XML string
Code:
testCustomer.ToXml();

Produces:

John
Smith
35



ToXml(Stream stream) -> Serializes the object to XML and writes it to the stream
Code:
testCustomer.ToXml(myStream);


ToXml(string fileName) -> Serializes the object to XML and writes the XML string to the file specified.
Code:
testCustomer.ToXml("c://test.xml);

If you are interested in my project you can download it from here.
Or you can simply download the Extensions.dll from here and import it into your project.

All extension methods are in the namespace System. I know that this is not the way how to do it but so you don't have to add a using directive because System is by default present.

XPath

For them of you which do not know what XPath is; it is a very powerful query language for XML data. But it can also more than querying data; it can also compute values, find the max or min of an attribute and even produce a different output format. For example it is possible to write HTML code with XML data. C# provides different classes to execute XPath queries on XML files which are located in the "System.Xml.Xpath" namespace.
The problem, at least for me, is that I do not use XPath so often as that I always remember the sometimes tricky XPath-Syntax. Here I found it very helpful to have a graphical tool where I can type in my query and see the results of the query. I found such a tool which is freeware; Sketch Path. It is a very powerful tool which not only shows you the result of a query but also assists you when writing a query by providing common operations and selectors.

I can only encourage you to try XPath when working with XML data because it really makes it easier to get the data you want. Especially if you use XML files instead of a database. XPath can be seen as the SQL for XML files.

Here there is a screenshot of Sketch Path where I searched in a list of customers for all customers which are older than 50. The query is quite simple:
//Customer[Age>50]


Another nice thing which is very helpful is that if you select a node then it shows you the path to this node which can help you creating your query:



Here you can find a tutorial on XPath Syntax.

Friday, September 5, 2008

TreeView node font problem

Recently I encountered the following problem. I needed to set the font style of some nodes in a treeview at runtime to bold; but after setting the NodeFont property of the node the font changed correctly, but the text of the node was cut off.

This screenshot shows the problem:


The solution to the problem is to add an empty string to the Text property after setting the NodeFont property:

this.treeView1.SelectedNode.NodeFont = new Font(this.treeView1.Font, FontStyle.Bold);
this.treeView1.SelectedNode.Text += string.Empty;


The problem is also known at Microsoft and I found this workaround here.

This screenshot shows the correct text:

Monday, June 16, 2008

Enhanced combobox with readonly and working value member

As I had several problems with the standard combo box of the .Net 2.0 Framework such as the missing read only property or the not working value member property (if not using a datasource), I decided to write my own improved combo box. To change the default combobox to my needs I overwrote the OnPaint() mehtod and provided some additional methods.

With the enhanced combo box you can finally specify a value member without having to use a datasource as you can see in the code below:
Customer customer1 = new Customer();
customer1.FirstName = "John";
customer1.ID = 1;
customer1.LastName = "Smith";

Customer customer2 = new Customer();
customer2.FirstName = "Marco";
customer2.ID = 2;
customer2.LastName = "Polo";

this.cmbTest.Items.Add(customer1);
this.cmbTest.Items.Add(customer2);

this.cmbTest.DisplayMember = "FirstName";
this.cmbTest.ValueMember = "ID";

Or you can use a datasource:
Customer customer1 = new Customer();
customer1.FirstName = "John";
customer1.ID = 1;
customer1.LastName = "Smith";

Customer customer2 = new Customer();
customer2.FirstName = "Marco";
customer2.ID = 2;
customer2.LastName = "Polo";

Customer customer3 = new Customer();
customer3.FirstName = "Tom";
customer3.ID = 3;
customer3.LastName = "Hanks";

List customers = new List();
customers.Add(customer1);
customers.Add(customer2);
customers.Add(customer3);

this.cmbTest.DataSource = objects;

this.cmbTest.DisplayMember = "FullName";
this.cmbTest.ValueMember = "ID";

Additionally you can register for different object types a display and value member. This gives you a lot of flexibility when you have to show information of different objects in the same combobox.
To register a new type call the "RegisterType" method and pass it the type of the object, the name of the property which is used as display member and the name of the property which is used as value member.
this.cmbTest.RegisterType(typeof(Customer), "FirstName", "PK");

To unregister a registered type call "UnregisterType" and pass it the type you want to unregister.
this.cmbTest.UnregisterType(typeof(Customer));

To modify the display and/or value member of a registered type call "ChangeValueMember" or "ChangeDisplayMember" respectively and pass it the new name of the property you want to use.
this.cmbTest.ChangeDisplayMember(typeof(Customer), "FullName");
this.cmbTest.ChangeValueMember(typeof(Customer), "LastName");
Of course all this operations can be performed at runtime and the changes are immediately visible in the combo.
To obtain the value of the selected item, simply call "SelectedValue".
Console.WriteLine(this.cmbTest.SelectedValue.ToString());
To get the selected object simply call "SelectedItem" and cast it to the correct type.
Customer selectedCustomer = this.cmbTest.SelectedItem as Customer;
if (selectedCustomer != null)
{
...
}
NOTE: If the combobox has to visualize a type which is not registered it calls the ToString() method of the object and uses that string.

Now I'd like to show you the read only property. The enhanced combobox provides a read only property which disables the drop down button and changes the back color of the combobox to "Control". The read only property is not a real read only because it is not possible to select and then copy the visible text. The most important point is that you can change the fore- and backcolor of the combobox when it is in read only because it is not very easy to read the text of a disabled combo box. The images below show what I mean.

This is a disabled ComboBox:


This is a read only ComboBox:


You can set any color as read only back- and fore color you like:



That's all about my enhanced Combo Box. I hope it helps someone to achieve what he wants. If you have suggestions on how to improve it or you found a bug, feel free to leave a comment.

You can download the DLL from here and simply drag and drop it to your visual studio toolbox.
Or you can get the source code with a sample tool which shows how to use it from here.

Saturday, June 14, 2008

Problems with Google Earth

Lastly I updated Google Earth to the latest version and after I started it I saw the following:


After searching the Internet I found the page of Google where they give some points which should be checked; such as: install the latest display driver, ...
But I already had the latest drivers.
While browsing trough the options of Google Earth I found that the display mode can be changed. After changing it to DirectX it worked correctly.

To change the setting:
1. go to the options


2. And then change the graphics mode to DirectX


Related links:
Google Earth

Thursday, May 15, 2008

Working with XML files

During my work as developer I have quite often to do with XML files. They are very popular and many data exchange is done with XML and also the file format of Office 2007 is based on XML. To provide a compatibility and avoid parsing errors it is a good idea to create an XML Schema file (.xsd) which describes which structure a XML must have. This allows then to validate an XML file and check if there are errors. Since I am not very good in writing XML Schema files (and often I have no time) I use a tool of Microsoft to generate an XML Schema file from an already existing XML file. The tool is included in the .NET frameworks 1.1 to 3.5. You can simply search in your "C:\Program files" folder for "xsd.exe" and you will find it.
The tool is a command line tool but very very easy to use. To get a schema out of an xml file perform the following steps:
  1. Create an XML file with the desired structure (for simplicity on the desktop)
  2. Search and copy the file "xsd.exe" to the desktop
  3. Open a command line window (Windows key + R -> type "cmd") or (Start -> Run... -> type "cmd")
  4. Navigate to your desktop folder
  5. Then type "xsd.exe myfile.xml"
  6. Use the created file "myfile.xsd" as base for your xml file
Even simpler is to use the freeware tool "XMLFox Advance". You can download it from here.
This applications helps you to create xml files and afterwards you can create the XML Schema file from it.
To validate an existing XML file against an existing XML Schema file with XMLFox you have to modify the preferences of the tool. Go to "Tools->Preferences" and check their the point "Perform validation against XSD schema". After this you can open an XML file with the application, go to the "Script" tab and click on validate. You are asked now which xsd file you want to use. After you selected one the validation is performed and possible errors are displayed in the list at the bottom.

Saturday, April 26, 2008

Who is faster??

Friday 24. of April I attended a conference which was organized by the dotnetpro magazine. The theme of the conference was Jump! and it was intended to give developers an overview of the new features of Visual Studio 2008, .Net framework 3.5 and C# 3.0. It was very interesting to see the new technologies and in which direction we are going. Something that impressed me was the new query language LINQ which can be used to query many kinds of data such as lists, xml files or databases. I was curious about the performance of this new technology and therefore I did some performance tests. I wanted to compare the traditional for loop, the nowadays mainly used foreach loop, the FindAll method of the collections class and LINQ. I executed every "method" two times because especially for LINQ this makes a big difference. The task that each "method" had to perform was to find all values which are bigger than 5 in a list of integers which contains all together 1,000,000 elements and add it to a result list. The result list contained about 400,000 elements because I filled it with a random number between 0 and 10.
Since under windows it is almost impossible to get accurate performance results because services and applications in the background interrupt my test application I run it altogether 10 times and then I took the least value for every "method". I was very impressed of the results, but first I will show you the code that I used:
This is the simple for loop that everybody knows how it works.
for (int i = 0; i <> 5)
result.Add(numbers[i]);
}

Here we have the well known foreach loop which is and should be used.
foreach (int num in numbers)
{
if (num > 5)
result.Add(num);
}

This the FindAll method of the collections class. It uses a predicate to decide which elments should be returned and I used an anonymous delegate to state my condition.
result = numbers.FindAll(new Predicate(delegate(int i) { return i > 5; }));

And finally here we have the LINQ query which looks like SQL and allows to make structured queries in the code. The var keyword in front states that the compiler decides of which type the variable "res" is. In this case it will be a collection of integers.
var res = from num in numbers
where num > 5
select num;

To talk about syntax; I prefer the LINQ syntax, because it is compact, structured and SQL like which many developers know quite well. Moreover when you have to make grouping and you do this with a foreach loop then you require much more lines of code as when you do it with LINQ. And as a speaker on the conference said:
More lines of code contain more errors.

Ok here there is the result of my measurements:



As you can see on the chart above, LINQ is by far the fastest "method" to perform such "queries". I was very impressed by the velocity. The difference between the first run and the second run lies in the implementation of LINQ. A speaker on the conference said that behind the scenes they build a binary tree and use it for searching. Therefore when this tree is build once all following queries are very very fast, also if you change the search condition.
Other things that you can see from the chart is that the good old foor loop is compared to the foreach and the FindAll "methods" the fastest. Despite this fact I will use the foreach loop in future because it is more structured and requires less thinking about the underlying array, list,... because the collection class does the work for you. I was disappointed of the performance of the FindAll method of the collection class. It was the slowest in the test. This could be because it uses predicates and anonymous delegates which may use more resources. The syntax of the FindAll is also compact and after some learning you know how to create anonymous delegates. The advantages of the methods of the collection class such as FindAll, Find, ConvertAll,... is that this features are available already under the .Net 2.0 framework and that you need only one line of code to do such "queries". The big disadvantage is as already said above that it is the slowest method to find a list of elements which satisfy a condition. For the other methods (Find, ConvertAll) I will maybe do some tests to see their performance.

If you are interested to run this performance test on your own machine you can download it here.

Tools used:
Microsoft Visual Studio 2008 Express Edition

Wednesday, April 9, 2008

Dynamic number of parameters

Lastly I realized a very interesting feature of C#; the possibility to have a dynamic number of parameters for methods. This feature can easily be used in any method by specifying the "params" keyword and then providing an array of objects which holds the parameters. This technique allows you to create interesting methods and giving you the possibility to make your code shorter and better understandable.
First of all I'd like you to show an add method which accepts dynamic number of parameters.
public static int Add(params int[] numbersToAdd)
{
int sum = 0;
foreach (int number in numbersToAdd)
{
sum += number;
}
return sum;
}

It can be called in the following two ways:
int[] numbers = new int[4];
numbers[0] = 3;
numbers[1] = 8;
numbers[2] = 22;
numbers[3] = 2;
Console.WriteLine(Add(numbers));
/* OUTPUT
* 35
*/

or
Console.WriteLine(Add(3, 8, 22, 2));
/* OUTPUT
* 35
*/

Which version do you like more? I prefer the second one because I don't have to create an array of integers. Sure this method makes not really sense but it is only for demonstration purposes.
Another interesting method could be written which is the "Concat" method. It basically concatenates every object passed as parameter to a string and returns it:
public static string Concat(params object[] objects)
{
StringBuilder sb = new StringBuilder();
foreach (object obj in objects)
{
sb.Append(obj.ToString());
}
return sb.ToString();
}

The usage of this method would be the following:
Console.WriteLine("\n" + Concat("hello world ", 4, " ", true));
/* OUTPUT
* hello world 4 True
*/

Two other methods which could be interesting are the "Copy" and "CreateAndCopy" methods. The "CreateAndCopy" method takes an object as parameter, creates a new instance of the same type and copies the properties which are specified by their name in the parameters. In addition it is a generic so that no cast is necessary and it can be used with any object. Note that when calling this method the type has not necessarily be specified because C# defers the type from the object passed.
public static T CreateAndCopy<T>(T source, params string[] propertiesToCopy)
{
T target = (T)System.Activator.CreateInstance(typeof(T));
foreach (string propertyName in propertiesToCopy)
{
PropertyInfo property = typeof(T).GetProperty(propertyName);
property.SetValue(target, property.GetValue(source, null), null);
}
return target;
}

It can be used like this:
MyObject o1 = new MyObject();
o1.Text = "hallo";
o1.Number = 99;
o1.Boolean = true;

Console.WriteLine(o1.ToString());
/* OUTPUT
* MyObject:
* Text -> hallo
* Number -> 99
* Boolean -> True
*/

MyObject newObj = CreateAndCopy(o1, "Text", "Boolean");
Console.WriteLine(newObj.ToString());
/* OUTPUT
* MyObject:
* Text -> hallo
* Number -> 0
* Boolean -> True
*/

The "Copy" method does something similar but it accepts a destination object to which the values of the specified properties are copied to:
public static T Copy<T>(T source, T destination, params string[] propertiesToCopy)
{
foreach (string propertyName in propertiesToCopy)
{
PropertyInfo property = typeof(T).GetProperty(propertyName);
property.SetValue(destination, property.GetValue(source, null), null);
}
return destination;
}

CONCLUSION:
The possibility to specify variable number of parameters may sometimes help to make the code easier to read and better understandable but in some circumstances it is better to create a class which holds all the required values and pass an instance of it to a method.

Monday, April 7, 2008

Generic progress dialog

Quite often I have to perform long operations in an application and then I want to show a progress bar to the user that he can see that the application is working and how long it will take. My requirements for the progress bar dialog are:
  • it should be generic and therefore not be tied with the work which has to be done
  • it should not block or freeze the main application
  • the user must have the possibility to abort the operation
It turned out that it is quite challenging to meet all these requirements. With different approaches I had different problems and could not fulfill my requirements. For example there was a version where the progress dialog was not updated or the user could not abort the operation. After some trying I found a quite usable solution. The main application uses a backgroundworker to do the work; this has the advantage that the computation is done in a different thread and the backgroundwoker provides cancel and progress notification. My progress bar dialog is started also in its own thread to make sure that its graphics are not blocked and updated when needed. With this "architecture" it is even possible that the main application performs some other operations while a heavy work is done and the progress shown to the user. The progress dialog provides all its functionalities through static methods which access a "private singleton". This means that the developer never gets an instance of the progress dialog and that at most one instance of the progress dialog exists. To notify the main application about the cancel event I used an event with a delegate. Therefore the main application can do what it wants when the user presses cancel.
When the user presses cancel then a message box is shown which asks if he really wants to abort. The nice thing with this implementation is that while this message box is shown the computation goes on and is not blocked.

The following code shows the progress bar, sets the title and message, assigns a method to the cancel event and starts the computation if the background worker is not already working:
if (!this.backgroundWorker.IsBusy)
{
this.Enabled = false; /*lock the main application*/
ProgressDialog.Show(max);
ProgressDialog.SetTitle("this is the title");
ProgressDialog.SetMessage("I am the message for the very long task. Please be patient and wait...");
ProgressDialog.CancelEvent += new ProgressDialog.CancelEventHandler(pd_CancelEvent);
this.backgroundWorker.RunWorkerAsync();
}

Important is to set the cancellation property of the background worker to true; this is best done in the designer or in the constructor of the main form:
this.backgroundWorker.WorkerSupportsCancellation = true;

The computation is done in the do_work event of the background worker. Here is important that in the loop the check for the cancel event is done because otherwise the backgroundworker will not stop on cancel. To update the progress bar it is enough to call the SetValue method of the progress dialog. This is only a very stupid operation for demonstration:
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < max; i++)
{
/*this check is needed in order to abort the operation if the user has clicked on cancel*/
if (this.backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}

ProgressDialog.SetValue(i); /*update the value*/
Console.WriteLine(i);
}
}

Another thing that I have to mention. In debug mode there occurs always an exception which says that this operations are not thread safe. Till now I did not had the time to look how I can make this code thread safe, but as soon as I have a thread safe version (if one exists) I will post it.
UPDATE:
I finally had the time to learn how to write thread safe method calls. The code below shows how it is done. First you have to check if the mehtod was called by a Thread other than the own Thread. This does the property "InvokeRequired". If so a delegate is created and the method is called with "Invoke".
public static void SetTitle(string title)
{
if (instance.InvokeRequired) /*if another thread called this method*/
{
SetTitleCallback s = new SetTitleCallback(SetTitle);
instance.Invoke(s, title);
}
else
{
instance.Text = title;
}
}

You can download the full demo project here.

Finally a screenshot on how my progress bar dialog looks like:


If you have suggestions, ideas or You know how to improve this code or if You have a thread save version You are welcome to post a comment.

Tuesday, March 4, 2008

How to draw a disabled control?

Recently I had to overwrite the OnPaint method of a button because I needed to draw a gradient background. My button had to display images and text. As the button should also have the disabled state where the image is gray scale I did not know how to get such an effect. After some research I found the ControlPaint class which is very useful not only in my case. It basically helps you to draw controls or part of controls such as the drop down button for a combo box and so on.
On the following picture you can see how this may look like:


The code to accomplish this is the following:
public class MyButton : Button
{
protected override void OnPaint(PaintEventArgs pevent)
{
Graphics g = pevent.Graphics;
g.FillRectangle(Brushes.White, pevent.ClipRectangle);
g.DrawRectangle(new Pen(Brushes.Black), pevent.ClipRectangle);
if (Enabled)
{
if(Image != null)g.DrawImage(Image, 0, 0);
g.DrawString(Text, Font, Brushes.Black, new PointF(100, 0));
}
else
{
if(Image != null)ControlPaint.DrawImageDisabled(g, Image, 0, 0, Color.Transparent);
ControlPaint.DrawStringDisabled(g, Text, Font, Color.Transparent, new RectangleF(100, 0, 100, 20), StringFormat.GenericDefault);
}
}
}
The class ControlPaint offers also other usefull operations and you can take a look at all its members here.

Tuesday, February 12, 2008

Wrong time under Vista in a domain

Recently I faced the following problem: my work computer is in a domain and unfortunately the clock of the server who provides the time for all clients is wrong. After trying to change my local clock I succeeded but only for a couple of minutes because then the old wrong time was used again. After an unsuccessful search on the Internet I found myself a solution for my problem. There exists a service which is called “Windows Time” and its description is:

“Maintains date and time synchronization on all clients and servers in the network. If this service is stopped, date and time synchronization will be unavailable. If this service is disabled, any services that explicitly depend on it will fail to start.”

After stopping this service and setting its start type to manual the problem was resolved.

CAUTION:

I do not know if switching off this service causes other things to not work correctly any more but till now I did not had any problems.

Thursday, January 31, 2008

Object - Relational converter

Are you also bored of writing all these sql statements which are needed to persistently store your objects into a database? 80% of these sql statements are inserts, updates or deletes and can be a quite an amount of work to write them especially if you have objects with more than 10 properties. Additionally there is maybe a file which is often called something like “database manager” which contains all this stuff and grows and grows with every new class that you write.
I was faced with the same problem and wanted to do something against this problem. If you are starting to build a project I would suggest you to use a free object relational mapper such as Castle Active Record which takes care of all the database stuff and makes your life a lot easier. It supports by far more features and supports different DBMS. If you are already within development or you do not want to use an object relational mapper or you simply do not want to inherit all your classes from a base class (which is used often used by object relational mapper) you could consider to use my approach.
I created a small object relational converter which is able to generate insert, update and delete statements for you based on an object that you pass as parameter. Additionally it provides the possibility to create objects from a datatable or datareader object.
I developed this code for Microsoft SQL Server Express Edition and therefore if you use another DBMS or you need to add another data type you have to change the “ToSQL” method which is responsible to convert the different data types into their correct sql representation:

/* This method is responsible to convert the datatypes into their corresponding */
/* sql representation. Change it if you encounter problems or if a data type */
/* needs special treatmend. */
private static string ToSQL(object obj)
{
if (obj is string || obj is Boolean)
return "'" + obj.ToString() + "'";
else if (obj is DateTime)
return "'" + ((DateTime)obj).ToString(DATE_TIME_FORMAT) + "'";
else if (obj is decimal)
return obj.ToString().Replace(',', '.');
else
return obj.ToString();
}

To realize my object relational converter I used reflection and additionally the objects which should be converted have to provide some additional information such as the table name, the column name for each property and the primary key. With reflection I obtain all public, not inherited properties and use them to create the SQL statements. If you want a different behaviour such as you want to include also inherited members then you have to modify the “GetProperties” method according to your needs:

/* This method is responsible to obtain all public, not inherited properties of an object. */
private static PropertyInfo[] GetProperties(object obj)
{
return obj.GetType().GetProperties(
BindingFlags.DeclaredOnly |
BindingFlags.Instance |
BindingFlags.Public);
}

Another thing that you should know is that you have to take care to establish a connection to your DBMS and to execute the queries. My code does only the conversions.
Finally I would like to state how a class must look like in order to use my object relational converter. You have to specify for the class the table name and for each property it’s associated column name in the database.
CAUTION: DO NOT USE RESERVED KEYWORDS OF THE SQL LANGUAGE BECAUSE THIS IS NOT CHECKED AND MAY CAUSE UNEXPECTED PROBLEMS!!
If the property represents the primary key of the table then you have to add a true because the primary key is needed for the update and delete statement. Here is now a sample class:

[Table("myTable")]
public class TestObject
{
private int table_pk;
private string text;
private DateTime datetime;
private int number;
private bool boolean;
private decimal decimalNum;

[Column("mytable_pk", true)]
public int Table_PK
{
get { return table_pk; }
set { table_pk = value; }
}

[Column("datetime")]
public DateTime Datetime
{
get { return datetime; }
set { datetime = value; }
}

[Column("number")]
public int Number
{
get { return number; }
set { number = value; }
}

[Column("text")]
public string Text
{
get { return text; }
set { text = value; }
}

[Column("boolean")]
public bool Boolean
{
get { return boolean; }
set { boolean = value; }
}

[Column("decimalnum")]
public decimal DecimalNum
{
get { return decimalNum; }
set { decimalNum = value; }
}

public TestObject()
{
this.table_pk = 999;
this.number = 5;
this.text = "this is a test string";
this.datetime = DateTime.Now;
this.boolean = true;
this.decimalNum = new decimal(1.5);
}

public override string ToString()
{
return "pk = " + this.Table_PK + ", datetime = " + this.Datetime.ToLongDateString() + ", number = " + this.Number.ToString() + ", text = " + this.Text + ", boolean = " + this.Boolean.ToString() + ", decimal = " + this.DecimalNum.ToString() ";";
}
}
And here some sample code on how to use the Object - Relational converter:

TestObject a = new TestObject();
string sql = ObjectToSqlConverter.CreateInsertStatement(a);
sql = ObjectToSqlConverter.CreateUpdateStatement(a);
sql = ObjectToSqlConverter.CreateDeleteStatement(a);

You can download the whole project and a small sample from here.


If you have suggestions or you found an error feel free to write a comment and tell me about them.
I give you this code “as is” without any warranty that it works or that it does not cause problems or delete/modify important data. Use it at your own risk in your private and commercial projects and feel free to modify it.


Related links:
SQL Zoo (provides SQL statements for actual DBMSes)
Reserved words in standard SQL
Microsoft SQL Server datatypes and corresponding .NET datatypes

Hide selection in DataGridView

Today I was faced at work with the problem that when there is a datagridview always the first cell/row/column depending on the selection mode is selected. I looked therefore for a property or method to have nothing selected. The data grid view provides a method called “clear selection” which can be called with

dataGridView1.ClearSelection();

but for some reason this did not work for me. I tried to create a new project and to do the same thing and suddenly the “clear selection” method worked perfectly. To resolve my problem I finally used the following code:

foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
cell.Selected = false;

This simply takes the list of selected cells and sets the "Selected"-property to false. This can also be done with only the rows or columns with the following code snippets:

foreach (DataGridViewRow row in dataGridView1.SelectedRows)
row.Selected = false;

foreach (DataGridViewColumn column in dataGridView1.SelectedColumns)
column.Selected = false;

If you use the version for individual cells you cover also the row and column selection. So it is not needed to have all three loops.
I tried also with the code
if(dataGridView1.SelectedCells.Count > 0)
dataGridView1.SelectedCells[0].Selected = false;

Which surprisingly did produce an error in the project but worked when I tried it in the new "clean" project. Please note that this code can only be used if multiple selection is not allowed!
I could not find out what where the differences between the empty project and my other project but if you encounter a similar behaviour the foreach loop should solve the issue; at least id did for me :-)


Tested with:
Visual Studio 2005 Express Edition
.NET Framework 2.0

Sunday, January 20, 2008

Site layout improved and syntax highlighting added

Thanks to the article about a syntax highlighting plug in of my friend Juri I was finally able to improve the code parts on my blog. It is now better readable and in addition the syntax is highlighted which makes the code even better readable and understandable. Another change that I made which you may have noticed while reading this post, is that i enlarged the content of my page. There is now more space for the posts which make them better readable. I would like to thank my friend Juri which helped me to realize this. Thanks :-)

Enjoy my blog!!

Thursday, January 3, 2008

Free installer for your applications

If you are a software developer like me and you developed some applications at home that you want to provide to others it is a good idea to have an installer which makes it easier to distribute your software. Since installers are often quite expensively I would like to point you to a free application that I use.
The tool is called "Create Install Free" and is available as free but also as commercial version which provides some additional features which are related mainly with branding. This tool takes a folder which contains the files of your program and creates an executable file which basically copies your files to the directory specified by the user. Additionally it provides the possibility to add a short cut to Start -> Programs as well as a desktop short cut. Some other features are to add a license text which has to be accepted by the user, a readme text, an uninstaller, inserting keys into the registry and customizing the executable file symbol. An important feature is that you can select the installer language from a list of many languages to adjust it for your needs.
I used it for several projects and I can only suggest it. After all it is freeware so there is nothing that prevents you from trying it out.


Some screenshots:

Here you see the output settings where you can specify the folder, the name of the executable, the icon of the executable and the type of setup.



This screenshot shows the possibility of the tool to set up the installer language and the name of the application.



The dialog settings allow you to provide a readme and a license file which are shown to the user during installation. Additionally you can set up some properties which dialogs should be shown.



Here we see the Run settings which basically lets you specify which file should be started after installation.



This screenshot shows the uninstaller properties which gives you the ability to include an uninstaller to your application which should definitely be there.


Related links:
Homepage of Create Install Free

Portable Apps

I own an external hard drive and since I have to help quite often kin and kith with their computer problems I thought it would be nice to have the most important applications with me. I looked therefore for a possibility to put applications on the external hard drive in order to run them without installation. After looking around the internet I found a very interesting tool which is called Portable Apps. It is installed on the external hard disk and an autorun mechanism is added in order to start it when the hard disk is plugged in. The Portable Apps tool adds an icon to the systray (or better notification area) which opens a menu which looks like the windows menu when clicking on start.

This menu now provides access to all the different applications which are present on the external hard drive. By selecting one of them the according application is started without the need of any installation on the host computer. This has the advantage that the registry of the host computer is not affected and also no hard disk space is required. Additionally to the applications there are folders to easily access documents, music, pictures or videos.

Additionally it provides a backup function to easily back up or restore files on the external hard drive as well as a search functionality to search the drive, the computer or the web. At the bottom of the menu the free disk space is shown.

The list of applications in the list can be extended as needed. For some applications there exists a “Portable Apps version” which can be downloaded and installed on the homepage of portable apps but it is also possible and very easy to integrate other applications. As I tried to integrate different applications I can say that applications which do not require an activation key can be added to the list of applications because the activation key is often stored inside the registry and requires an installation routine. The most easy way to add a new application is to download it as archive without installer. It can then be put into the “PortableApps” folder on the external hard disk. The only thing to know is that in the menu there will be shown all exe files which are on the following path: Z:\PortableApps\application folder\application.exe; the name of the exe file is listed in the list of applications. Some system related applications such as firewalls can not be made portable because they have to directly interact with the underlying system and require an installation.

A quite large and good list of portable applications can be found here. From that site I took most of the applications that are present on my application list.

After I installed all applications that I need on the external hard drive I started to miss them when the external hard drive was not plugged in. I simply had to copy the “PortableApps” folder and the file “StartPortableApps.exe” to my local hard disk and it works fine. I like this because for example all of the sudden I get an Open Office file and to open it I do not want to install Open Office on my computer. So I start portable apps and there I have Open Office available and I can open, modify and save Open Offices files without having to install it.

Her now a list of applications that are present on my application list:

7-Zip Portable: utility for manipulating archives

Abakt: simple backup utility with many configuration options

Auto-Backup Win: a tool to backup all important files of a windows installation such as activation files, Outlook Express E-Mails, My Documents, and many others…

CCleaner: a tool to clean the registry, the hard disk and the autostart entries

CDex Application: a tool to rip an audio cd to mp3 files

ClamWin Portable: a portable virus scanner

Data Recovery Application: a tool to recover deleted data

File Assasin: a tool to delete locked files from the system; useful to remove trojans

Firefox Portable: the successful internet browser Firefox

Gaim Portable: instant messenger which supports different protocols

JkDefrag GUI version: a very good defragmenter application

Notepad++ Portable: text editor which provides syntax highlighting for many different programming languages

Open Office Portable: open source office suite

ReNamer: a tool to rename files and folder according to rules

Safarp: simple and fast uninstall utility which makes the slow windows uninstall dialog obvious

Siginet’s Driver Grabber: a tool to backup all installed drivers; useful when formatting the hard drive and reinstalling windows

SilentNight Micro Burner: a tool to burn cd’s and dvd’s

StartUp Lite: a tool which checks the autostart entries and makes suggestions which entries can be removed in order to accelerate the windows start

Sudoku Portable: sudoku game to pass the time

Sumatra PDF Portable: simple PDF reader

System Information for Windows: a very good tool to get information about hardware and software; provides additional tools such as uncovering password fields,…

Thunderbird Portable: very good e-mail client

Toucan: a tool for advanced users to synchronise, backup and encrypt their data

VLC Media Player Portable: a media player which plays most of the actual video and audio formats

XP-AntiSpy: a tool which makes some settings to prevent windows from “talking” with Microsoft


Related links:
Homepage Portable Apps
Homepage The Portable Freeware