Sunday, 14 April 2013

My Learnings with DataGridView in WinForms - Part 3

 Dynamically change images based on values based on other grid column
 
In this part, we will learn how to display appropriate images based on status(or any other grid column value). Let’s continue with the same code sample as in Part-2 and Part1.

Let’s consider a scenario that if a book is available we would like to display an image button “Buy” so that user can place order for that book. In case book is Not Available, we would let the user select “SMS” option so that whenever book is available user will be notified through SMS.

Status
ImageToDisplay
ImageIcon
Available
Buy
 


Not Available
SMS
                      
 

Let’s modify our grid in previous post to include one more column for Buy/SMS.
1.

 2.
 
3. New datagrid column will be added as shown.
 

4. Add CellFormatting event to the datagrid(dgvDashboard).
 
5.             Modify the code in dgvDashboard_CellMouseMove function as below. This function updates the mouse cursor to hand for newly added(Buy/SMS column).
 
private void dgvDashboard_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
        {
            //Skip the Column and Row header
            if (e.ColumnIndex < 0 || e.RowIndex < 0)
            {
                return;
            }
            //Check the condition as per the requirement casting the cell value to the appropriate type
            //column index 4 is delete column, column index 5 is Buy/SMS column
            if (e.ColumnIndex == 4 || e.ColumnIndex==5)
                dgvDashboard.Cursor = Cursors.Hand;
 else      {      dgvDashboard.Cursor = Cursors.Default;
}
6. Now add required images to the solution. Double  click on Resources.resx file from solution explorer.
 

Choose path of BuyNow and SMS images.
 
7.  Add the following code to cellformatting event.
private void dgvDashboard_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (!dgvDashboard.Rows[e.RowIndex].IsNewRow)
            {
                if (dgvDashboard.Columns[e.ColumnIndex].Name == "BuySMS")
                {
                    if ((dgvDashboard.Rows[e.RowIndex].Cells["Status"].Value).Equals("Available"))
                    {
                        e.Value = Properties.Resources.buy;
  dgvDashboard.Columns["BuySMS"].Tag = "Buy";
                    }
                    else
                    {
                        e.Value = Properties.Resources.sms;
  dgvDashboard.Columns["BuySMS"].Tag = "SMS";
                    }
                }
            }
        }
 
8. Let’s run the solution now and observe the output.
 

Oops!! Entire column contains “Buy” Image as status of all books is Available. To test properly lets change one of the row status to” NotAvailable”.
For this update the PopulateGrid() method as follows.
public IList<CourseEntity> PopulateGrid()
{
 List<CourseEntity> courseList = new List<CourseEntity>();
 courseList.Add(new CourseEntity { Id = "1", CourseName = "Asp.NET MVC3", Status = "Available" });
courseList.Add(new CourseEntity { Id = "2", CourseName = "Asp.NET MVC4", Status = "Available" });
courseList.Add(new CourseEntity { Id = "3", CourseName = "C#", Status = "Not Available" });
courseList.Add(new CourseEntity { Id = "4", CourseName = "Metro Apps", Status = "Available" });    
 return courseList;
 }
9. Now observe the output by running the solution again.

 
 Therefore, we are able to display appropriate images based on status column value. And also show hand cursor over them to make them clickable.
But nothing will happen as of now, if user clicks on BuyNow or SMS options. For that we need to write logic for “BuyNow” and SMS clicks.
Add the following code in MouseClick event of the datagrid.
private void dgvDashboard_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e){            //Skip the Column and Row headers
if (e.ColumnIndex < 0 || e.RowIndex < 0)  { return; }      
if (e.ColumnIndex == 4){  dgvDashboard.Rows.RemoveAt(e.RowIndex);}           
//if user click on Buy/SMS column   
         if (e.ColumnIndex == 5)            {
                //Add logic for Buy or SMS as per user selection
        if (dgvDashboard.Rows[e.RowIndex].Cells[e.ColumnIndex].Tag.Equals("Buy"))
                {
                    //Add logic for Buying the product
                    MessageBox.Show("You click on Buy Image in row " + e.RowIndex);
                }
                else
                {
                   //Add logic for sending sms
                    MessageBox.Show("You have clicked on SMS Image in row " + e.RowIndex);
                }
            }
        }
** Please notice that in step7 while assigning images to appropriate rows, we have also set tag property of image. This property helps us distinguish between Buy and SMS image clicks in same column.

Conclusion

We learnt how to dynamically change images based on values based on other grid column using cellFormatting Event.



1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete