Click here to Skip to main content
15,870,297 members
Articles / Desktop Programming / Windows Forms
Article

Asynchronous data loading and data binding with Windows Forms

Rate me:
Please Sign up or sign in to vote.
4.29/5 (6 votes)
15 Dec 2008CPOL3 min read 48.3K   1.8K   55   1
This article introduces a reusable library that contains two utility components for data binding and asynchronous data loading.

Screen01.JPG

Notification windows:

Deleted.JPGSaved.JPG

Error.jpg

Introduction

This article introduces a reusable library that contains two utility components I developed for performing data binding and asynchronous data loading with WinForms applications. The components I am introducing here are provided on an as-is basis, and are not claiming to follow any standard design pattern. However, they were developed to avoid some duplicate coding efforts that are required to implement simple binding scenarios in Window Forms applications. The article is solely based on Windows application environment.

Prerequisites

The components described in the article use three open source implementations:

  1. NHibernate (An open source ORM framework)
  2. ObjectViews (An open source data binding framework)
  3. NofifyWindow (A library posted in CP by Mr. Robert Misiak)

I would like to express my gratitude to these valuable frameworks and libraries, integrating which I have implemented the small utility components described in the article content below.

Background

If you've developed a WinForms application with data binding, you've encountered the daunting task of implementing a data binding feature supported throughout the application. Implementing the replicated methods for saving and deleting data as well as error handling is a boring and very bug-prone process when you are building something more exquisite than a demo test application. After my jiggling experiments with data binding, I developed two utility components:

1. Data Binder

It has all required features for a data navigator as well as to handle save, delete, and error handling. It also provides notification using a notify window.

2. Data Loader

It is a runtime invisible type of component that implements an async data loading behavior using a background worker, and provides some event notifications to consume the data fetched by the async operation.

Using the code

Data binder

It is a component with a user interface, hence we can create a new instance by using the toolbox of the Window Forms Designer. To add the control to the toolbox, select Choose Items from the context menu of the toolbox, and browse to the complied library (DataBinder.dll) of the attached project. After adding the control to a Windows Form, you can call the StartProgress and StopProgress methods to display and hide the progress bar.

VB

VB
'It will display the progress bar
databinder1.StartProgress()

'It will hide the progress bar
databinder1.StopProgress()

C#

C#
//It will display the progress bar
databinder1.StartProgress();

//It will hide the progress bar
databinder1.StopProgress();

For binding the control to any data source that implements the ICollection of IList, use the following syntax:

VB

VB
'This must be NHibernate session, an instance of ISession
DataBinder1.DAOObject = session
'This is type of entity that needs to be persisted
DataBinder1.EntityType = GetType(User)
'It contains any collection of entities
DataBinder1.DataSource = objectList
datagrid1.DataSource = DataBinder1.BindSource
'This will enable data binding between 
'UI controls and internal ObjectView instance
DataBinder1.SetBinding()
'This will enable the notification window 
'for and save and delete operation
DataBinder1.ShowNotification=True

C#

C#
//This must be NHibernate session, an instance of ISession
 DataBinder1.DAOObject = session;
//This is type of entity that needs to be persisted
 DataBinder1.EntityType = GetType(User);
//It contains any collection of entities
DataBinder1.DataSource = objectList;
datagrid1.DataSource = DataBinder1.BindSource;
//This will enable data binding between UI controls
//and internal ObjectView instance
DataBinder1.SetBinding();
//This will enable the notification window for and save and delete operation
DataBinder1.ShowNotification=True;

That's all that is required to keep running the data binder control.

Data loader

This component does not have a visible user interface, hence we can directly create an instance like any other variable declaration. The component supports generic declarations, so any valid entity (POCO) can be used to create a DataLoader instance; e.g.,

VB

VB
Dim ldr as New DataUtils.DataLoader(Of User)()
'After creating instance of DataLoader, 
'event subscription is required to catch some usefull
'events notification like Cancelled,Finished 

Private Sub ldr_Cancelled() Handles ldr.Cancelled
  MessageBox.Show("Operation cancelled")
  DataBinder1.StopProgress()
End Sub

Private Sub ldr_Finished() Handles ldr.Finished
    'Put any data binding code here
    userDataBinder.StopProgress()
End Sub

Private Sub ldr_LoadError(ByVal e As System.Exception) Handles ldr.LoadError
    MessageBox.Show(e.Message, "Error")
    DataBinder1.StopProgress()
End Sub

C#

C#
private DataUtils.DataLoader(Of User) ldr = 
               New DataUtils.DataLoader(Of User)();
//After creating instance of DataLoader, 
//event subscription is required to catch some usefull
//events notification like Cancelled,Finished 
ldr.Cancelled+=new CancelledEventHandler(ldr_Cancelled)
ldr.Finished+=new FinishedEventHandler(ldr_Finished)
ldr.LoadErrod+=new LoadErrorEventHandler(ldr_LoadError)

private void ldr_Cancelled() {
        MessageBox.Show("Operation cancelled");
        DataBinder1.StopProgress();
    }

    private Sub ldr_Finished() {
        //Put any data binding code here
        userDataBinder.StopProgress();
}

private Sub ldr_LoadError(System.Exception e) {
    MessageBox.Show(e.Message, "Error");
    DataBinder1.StopProgress();
}

Every data loader instance requires an NHibernate Session instance to fetch the data from the persistent store.

VB

VB
ldr.Session = session

C#

C#
ldr.Session = session;

Now, as a last resort, invoke the FetchAll method that will internally create a background worker and start fetching data records asynchronously. Meanwhile, the application may display a responsive UI, or may indulge in some other task. Once the data fetching gets completed, the application will receive a Finished or LoadError event depending on the outcome of the data retrieval operations.

VB

VB
ldr.FetchAll()

C#

C#
ldr.FetchAll();

That's all that is required for running a data loader component.

Although I have tried to keep the quality of this article on CP, I still believe that the components shared by the article does not follow any standard Design Pattern, and may not be efficient enough for providing a scalable solution. Anyways, I thought that it might be useful for someone, and might avoid some duplicate coding efforts.

Please share your view and comments related to this article; I will be happy to listen all those blessings. :)

History

  • Initial revision - Dec. 16 2008.

License

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


Written By
Architect
Canada Canada
Ashutosh is an avid programmer, who “lives to code”. One can always find him busy seeking challenging programming assignments on various complex problems ranging from Data management, Classification, Optimization, Security, Network analysis, Distributed computing.

He started his programming stint with “C”; he has also worked on C++, Visual Basic, JAVA, Perl, FoxPro, PASCAL, Shell Scripting, and Perl. Currently, he is proficient and working on C#.

His area of interest includes Distributed Computing, Analytic and Business Intelligence, Large Enterprise System Architectures, Enterprise Content Management.

He is an advocate of Open source and likes to share solutions with open source communities like
1.Stack Overflow
2. nHibernate
.

Award's :
Prize winner in Competition "Best article of May 2008"

Articles :
Click to see my CodeProject Articles

Blog :
Share a solution | Explore the .NET world

Link'd :


His Favorite(s) :
nHibernate - The best ORM.
nHibernate Contributed Tools

Comments and Discussions

 
QuestionHow works your component in my case Pin
sharfudeen5-Apr-09 23:48
sharfudeen5-Apr-09 23:48 

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

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