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