Hash

Binding a List with DataGridView

March 31, 2009 · 2 Comments

DataGridView control for WinForms was introduced in .NET 2.0 and VS 2005. Its a pretty flexible control offering a lot more than DataGrid control in the previous version. Recently I was looking for a control which inherently support embedded control in its cells and DataGridView came up as a strong candidate. It has a native support of some basic embedded controls like TextBox, CheckBox etc. I explored it a little more and found it extremely easy and quick to program. My usage of this control is not much advanced which I describe here.

It has been built for displaying relational data so you can bind it to a DataTable from the database or an array of business objects. What I have done here is that I used a BindingList object which is also provided with .NET and is a useful variant of List object. The advantage of BindingList is that it can act as a sink of events while simple List object can’t.  It provides a PropertyChangedEventHandler which is called when a row is added/updated or deleted. So you simple bind this list to your DataGridView and both objects will remain synchronized. If you add/delete/update something to one the other object will simple pick it up from the event. Have a look at this:

private void MyForm_Load(object sender, EventArgs e)
{
             FillUpDataGridView();
             MyDataGridView.DataSource = Settings.MyBindingList;
}

The method FullUpDataGridView reads some business objects from a data source into the BindList object and the next statement displays the data in the control. You also need to bind DataGridView columns to properties of these business objects to specify which properties are displayed and which are not and their respective order.

Binding properties with columns of DataGridView control

This image shows name of the propery FeedEnabled which has been bound with the column "Enabled". My business object looks like:

public class FeedViewRow : INotifyPropertyChanged
{
    private string _FeedUri;
    private bool _AutoUpdate;
    private bool _FeedEnabled;         // Parameterless constructor for serialization
    public FeedViewRow() {  }
    public FeedViewRow(string Uri, bool Auto, bool Enabled)
    {
        _FeedUri = Uri;
        _AutoUpdate = Auto;
        _FeedEnabled = Enabled;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public bool FeedEnabled
    {
        get { return _FeedEnabled; }
        set { _FeedEnabled = value; this.NotifyPropertyChanged("FeedEnabled"); }
    }
    public string FeedUri
    {
        get { return _FeedUri; }
        set { _FeedUri = value; this.NotifyPropertyChanged("FeedUri"); }
    }
    public bool AutoUpdate
    {
        get { return _AutoUpdate; }
        set { _AutoUpdate = value; this.NotifyPropertyChanged("AutoUpdate"); }
    }
    private void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

Keep a string property for TextBox and bool for CheckBox.  You object should implement the INotifyPropertyChanged interface.

After this you can simply [de]serialize the BindingList object. For serialization:

IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForAssembly();
IsolatedStorageFileStream File = new IsolatedStorageFileStream(StorageFileName,
FileMode.Create, FileAccess.Write, FileShare.None, Storage);
XmlSerializer Serializer = new XmlSerializer(typeof(BindingList));
Serializer.Serialize(File, this);
File.Close();
Storage.Close();

This will write out an XML of the whole list. Simple!

 

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET
Tagged: , , , , , , , , , , , ,

Using the Oracle DBMS_LOCK Package

March 31, 2009 · Leave a Comment

As a standard DBMS practice Oracle provides all sort of row level and table level locking mechanism for data integrity. This built-in locking mechanism is strongly coupled with database transactions e.g. a lock acquired through the LOCK command is released automatically at the end of the transaction. Sometimes you need explicit locking with full control and independent of the transactions. This feature is provided by DBMS_LOCK.

The other day I was stuck in a legacy system where I had to provide a locking mechanism on call to a stored procedure at the database level. The procedure is called from a web farm consisting of a number of web servers and I wanted to make sure that only one web servers accesses the procedure at any given time. Although I hated such a procedure in my database but that looked like the only solution to the problem without changing some fundamentals. The DBMS_LOCK package came for my rescue and here is what I learnt from it.

This package is available to the SYS user only (may be because of its significance and impact). So if you try to access it from another user you will get an error “IDENTIFIER MUST BE DECLARED”. The solution is to write  functions on top of the DBMS_LOCK package and grant access to those functions. The DBA can thus regulate which operations are allowed to the user and which are forbidden.

CREATE OR REPLACE PROCEDURE xmode_lock_procedure (lockhandle varchar2, v_result OUT number) IS
v_lock varchar2(200);
begin
dbms_lock.allocate_unique(lockhandle, v_lock);
v_result := dbms_lock.request(v_lock, dbms_lock.x_mode);
end;

Grant access on this procedure to the user:

GRANT ACCESS ON xmode_lock_procedure TO user1;

Granting access to public is never recommended due to sensitivity of this procedure.

Similarly a procedure which releases this lock can be written as:

CREATE OR REPLACE PROCEDURE lock_release (lockhandle varchar2, v_result OUT number) IS
v_lock varchar2(200);
begin
dbms_lock.allocate_unique(lockhandle, v_lock);
v_result := dbms_lock.release (v_lock);
end;

This will release the lock and in the meantime if another users requests a lock he will be blocked until this users releases the same lock. Note that the lock uniqueness is decided by the LOCKHANDLE parameter passed to the procedures.

The result returned by these procedures can be:

1: Timeout occurred
2. Deadlock occurred
3. Parameter Error
4. Already owned
5. Illegal lock handle

 

 

 


Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: Oracle · TechFactor
Tagged: , , , , , , ,

C# Winforms: Using a progress bar with Web Browser Control

March 31, 2009 · 2 Comments

The .NET web browser provides a number of different events including some which tells when the browser started navigating to a web page and when that navigation completed.

These events are:

private System.Windows.Forms.WebBrowser ItemBrowser;

 

this.ItemBrowser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.ItemBrowser_Navigating);
this.ItemBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.ItemBrowser_DocumentCompleted);
this.ItemBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.ItemBrowser_Navigated);

 

This shows the functions are being called at proper events. Now let us come to the code in those functions. The goal is to show a marquee in the status bar when a page is clicked and stop that marquee when navigation is fully complete.

private void ItemBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    BrowserLabel.Text = "Loading ... ";
    BrowserProgressBar.MarqueeAnimationSpeed = 80;
    BrowserProgressBar.Style = ProgressBarStyle.Marquee;
}

 

I have created two items in the status strip. A Label named BrowserLabel and a progress bar item named BrowserProgressBar. The text property of BrowserLabel is set to “Loading … “ when a hyperlink is created. And to start the marquee we set the style of progress bar to Marquee and its speed to 80. Note that as you increase the AnimationSpeed it will slow down. It will be fastest at 1 and slowest at 100 (I have set 100 as MaxSpeed, you can change that property as well).

Now we need to stop this animation when browsing is complete:

void ItemBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    BrowserProgressBar.MarqueeAnimationSpeed = 0;
    BrowserProgressBar.Style = ProgressBarStyle.Blocks;

    BrowserLabel.Text = "Ready";
}

 

I set the style back to Block and AnimationSpeed to “0”. Style is a property and it can start/stop the animation according to its value so you don’t need to call a “start” function as required in the previous versions. Also the value of Label is reset here.

One function is still remaining:

void ItemBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (!ItemBrowser.IsBusy)
    {
        BrowserProgressBar.MarqueeAnimationSpeed = 0;
        BrowserProgressBar.Style = ProgressBarStyle.Blocks;

        BrowserLabel.Text = "Ready";
    }
}

 

This function is also called when navigation is completed. Although in most cases the DocumentCompleted function is sufficient but bookmark links do not call that function so Navigated function will do in those cases.

 

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET · CodeProject
Tagged: , , , , , , , , , ,

C# Winforms: Create a Single Instance Form Using Singleton

March 31, 2009 · 8 Comments

A common practice in WinForms programming is to keep only one instance of a certain form in the application. A new instance of that form is never created and shown. I have previously written a small note on this topic and gave a solution here which I personally don’t like.

In this post I am presenting a much better solution which is based on the singleton pattern. Rather than each time looking for the form in a list of opened forms I make the constructor private.

Let us start with the Form:

public sealed partial class ThirdForm : Form
{

}

The class is sealed so it cannot be inherited. We don’t want a child create an instance of this class multiple times.

Now add these members and methods to the class:

private static readonly ThirdForm MyInstance = new ThirdForm();

This is the sole instance of this form. And the private constructor to avoid multiple instances outside the class:

private ThirdForm()
{
    InitializeComponent();
}

And the property to publish the sole instance:

public static ThirdForm OnlyInstance
{
    get { return MyInstance; }
}

Another functionality that you might want to add to your Form is a new Show method. And you may also want to know whether the form was already opened or your opened it. Here is the answer to these questions. Add this code to your form class to Show() or Select() if already shown.

public new void Show()
{
    if (IsShown)
        base.Show();
    else
    {
        base.Show();
        IsShown = true;
    }
}

A variable IsShown of type bool is added to the form to record the current state.

private static bool IsShown = false;

static ThirdForm()
{
    OnlyInstance.FormClosing += new FormClosingEventHandler(OnlyInstance_FormClosing);
}

private static void OnlyInstance_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
    IsShown = false;

    OnlyInstance.Hide();
}

The variable IsShown is set to false when the only instance of this form is closed. But remember its a singleton. We can’t let the only instance die so we catch FormClosing event and Hide() the form instead of closing it.

This solution looks elegant than looking for an opened form in an array but it has draw backs. You cannot catch the FormClosed event because it will never happen. The form is created only once so if your form is based on some volatile objects you will never see the change even if you close and open it again. May be I try to address these problems in another post some day. Spot On!

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET
Tagged: , , , , , , , , ,

Creating one-to-many relationship in NHibernate

March 31, 2009 · 9 Comments

We have recently brought in NHibernate in our environment and I was the first one in the team to do something real with it. It was going perfect until this one-to-many relationship and then I had to consult the architect in UK to get it going :( Infact I successfully implemented many-to-many but could not do one-to-many . *&#%&*#W(*(*&%#

Anyways, we had a class SearchCritera having a list of SearchCriterion. The mapping file looked like:

<class name="BusinessObjects.Search.SearchDocumentCriteria" table="searchdocumentcriteria">
<id name="Id" column="id">
<generator class="sequence">
<param name="sequence">pc_searchdocumentcriteria</param>
</generator>
</id>
<bag name="Criteria" lazy="false" cascade="all" inverse="true">
<key column="criteriaid"/>
<one-to-many class="BusinessObjects.Search.SearchDocumentCriterion"/>
</bag>
</class>
<class name="BusinessObjects.Search.SearchDocumentCriterion" table="searchdocumentcriterion">
<id name="Id" column="id">
<generator class="sequence">
<param name="sequence">pc_searchdocumentcriterion</param>
</generator>
</id>
<property name="FieldName" column="fieldname" type="string"/>
<many-to-one name="Id" class="BusinessObjects.Search.SearchDocumentCriteria" column="criteriaid" not-null="true"/>
<bag name="Expression" lazy="false" cascade="all" inverse="true">
<key column="criterionid"/>
<one-to-many class="Search.SearchDocumentCriterionOperatorValue"/>
</bag>
</class>

Look at the red line, it maps back to the parent class’s column Id. This is what I found in the manual and an example on the internet as well. But we were getting the error:

Unknown entity class: System.Int32

Later we found that we need to have a parent reference in the child class as well which make the relationship 2-way. So we added the following property in the SearchDocumentCriterion class:

public virtual SearchDocumentCriteria Parent { get; set; }

And the following change in the mapping file:

<many-to-one name="Parent" class="BusinessObjects.Search.SearchDocumentCriteria" column="criteriaid" not-null="true"/>

Note the Parent property instead of Id property. This solved the problem :D Anyone having a better solution for one-to-many relationship in NHibernate? Yes, I don’t like the two-way relationship.

 

 


Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET · CodeProject
Tagged: , , , , , , ,