Click here to Skip to main content
Licence CPOL
First Posted 17 Jul 2005
Views 35,230
Bookmarked 26 times

NullableComboBox

By | 17 Jul 2005 | Article
A combobox which can show null for business objects.

Introduction

This is a combo box which can bind to business objects and can show null values (empty).

Background

The problem with the combo box is that after you bind data to it, it is not possible to show an empty Text property. It is also not possible to delete an already selected value. This combo box can do both. It is designed that you bind business objects to it, but I think (never tried it) it should also work with .NET DataTables.

Using the code

I call the little trick I do "lazy binding". With this I mean, that I don't bind the data in the first place when you set the datasource. I wait until the user actually tries to drop down the combo box. So you have the effect that the user sees an empty combo box in the beginning. The deleting of already selected items works nearly similar. In that case (if the user press DEL or BACK button), I remove the databinding of the combo box (but still remember the datasource). The code itself is really simple:

The only interesting method is the one that does the data binding:

public void SetDataBinding(IList dataSource, object objectToModify, 
                                      string propertyName, string displayMember)
{
    // init combo box and delete all databinding stuff
    this.DisplayMember = String.Empty;
    this.Items.Clear();
    this.ValueMember = String.Empty;
    this.Text = String.Empty;

    // init private fields
    this.mDataSource = dataSource;
    this.mObjectToModify = objectToModify;
    this.mPropertyName = propertyName;
    this.mProperty = 
      this.mObjectToModify.GetType().GetProperty(this.mPropertyName);
    this.mDisplayMember = displayMember;
    this.mNullableMode = true;
    
    // get selected item
    object selectedItem = 
      this.mProperty.GetValue(this.mObjectToModify, null);

    // if not null, bind to it
    if (selectedItem != null)
    {
        this.DataSource = this.mDataSource;
        this.SelectedItem = selectedItem;
    }
    // do nothing and set datasource to null
    else
        this.DataSource = null;
}

The drop down event:

protected override void OnDropDown(EventArgs e)
{
    // if no datasource is set, set it
    if (this.mNullableMode && this.mDataSource 
           != null && this.DataSource == null)
        this.DataSource = this.mDataSource;

    base.OnDropDown(e);
}

And the key down event:

protected override void OnKeyDown(KeyEventArgs e)
{
    // if DEL or BACK is pressed set property to null and data source to null
    if (this.mNullableMode && (e.KeyCode == 
             Keys.Delete || e.KeyCode == Keys.Back))
    {
        // next line is very important:
        // without you may get an OutOfRangeException
        this.DroppedDown = false;
        this.DataSource = null;
    }

    base.OnKeyDown(e);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rainer Halanek

Software Developer (Senior)

Austria Austria

Member

Born and living in Vienna, Austria. Started with Pascal in 1993 and MS-DOS 5.0. After that a little C++ in OS/2 and loads of VBA with Access in Windows 95,98, NT. To get more professionel I started C# in 2002 and did some MCP exams on that. After working for my own company I got hired by different companies. Currently I'm employed at the Federal Chambers of Commerce as a Senior Software Engineer.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralDisplayMember does not work Pinmemberdavidlolo23:21 20 Apr '10  
GeneralRe: DisplayMember does not work PinmemberRainer Halanek23:27 20 Apr '10  
GeneralBug fix PinmemberEd.Poore23:58 15 Nov '06  
Just thought I'd let you know that an exception is thrown when you use SetDataBinding and then the value is being loaded from the data bound item at that time (I think).
 
Fix, I've put a flag to indicate when the SetDataBinding is entered and left and then in the OnSelectedIndexChanged override check that this is it hasn't been called from SetDataBinding and only executes the base event then not your custom code.
 
Sorry I havn't looked into it more I just don't have the time at the moment, but if you want more information just ask.  It may be I'm using this incorrectly but my fix seems to be working.
 
Also thanks for writing a nullable combobox been looking for one for ages and at least this one doesn't change the underlying objects, e.g. all the previous ones insert a special object into a list as a null.
 
Just one more thing, I havn't looked into but got a few ideas, when you enter the combobox for the first time (using the keyboard) the items havn't been loaded from the database, thus any keypress doesn't select an item because they havn't been loaded.  E.g. it you enter the box for the first time and press the down key I think that it should select the first item in the list.  Perhaps the way around this is in the SetDataBinding or constructor or whereever to load the list initially even if the databound item is null, but then reset the current item to null afterwards if required, this way the keyboard shortcuts should work.  I think, but then again I havn't looked but will do tomorrow maybe when I have more time.
 
Again thanks for the control

 

GeneralGreat! Pinmembercsg19:46 2 Nov '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 18 Jul 2005
Article Copyright 2005 by Rainer Halanek
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid