This is a migrated thread and some comments may be shown as answers.

Rowindex error after autosort

8 Answers 131 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Geert
Top achievements
Rank 1
Geert asked on 04 Jan 2011, 02:40 PM
Hello,

I have a grid which shows the structure of a folder. Everythings works perfect except when I sort the list with the auto sort method.

My first column is a imagecolumn. If the record is a file a file-icon is shown, if the record is a folder, a folder-icon is shown. I use the Cellformatting even for this.

This works perfect, but when I sort the grid the rowindex is always missing This is the error: e.CellElement.RowIndex 'e.CellElement.RowIndex' threw an exception of type 'System.ArgumentException' int {System.ArgumentException}


This is my code, column 6 is used to show the current file size, column 2 is the imagecolumn.

private void radGrdDocuments_CellFormatting(object sender, CellFormattingEventArgs e)
        {
  
            if (e.CellElement.ColumnIndex == 6)
            {
                if ((radGrdDocuments.Rows[e.CellElement.RowIndex].Cells["colType"].Value.ToString() == "1"))
                {
  
                    GridViewCellInfo sizeCell = this.radGrdDocuments.Rows[e.CellElement.RowIndex].Cells[e.CellElement.ColumnIndex];
                    radGrdDocuments.CellFormatting -= new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
                    sizeCell.Value = ConvertSizeToString(Convert.ToInt32(radGrdDocuments.Rows[e.CellElement.RowIndex].Cells["colActualSize"].Value));
                    radGrdDocuments.CellFormatting += new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
                }
            }
            if (e.CellElement.ColumnIndex == 2)
            {
                GridViewCellInfo imageCell = this.radGrdDocuments.Rows[e.CellElement.RowIndex].Cells[e.CellElement.ColumnIndex];
                radGrdDocuments.CellFormatting -= new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
                imageCell.Value = imgListPicto.Images[radGrdDocuments.Rows[e.CellElement.RowIndex].Cells["colIconType"].Value.ToString()];
                radGrdDocuments.CellFormatting += new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
            }
  
        }

8 Answers, 1 is accepted

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 04 Jan 2011, 03:43 PM
Hello,

If you are using CellFormatting to add an image to a cell, then may I suggest a few pointers.
1: Don't inpect column index. This will change if you allow columns to be moved. Use column name instead
2: The CellFormatting event should always be allowed to run as the grid re-uses each cell (UI virtualization)
3: you don't actually need to inpect the row index..
Have a look at the simple example below. This adds an image to the cell in the "Name" column if the Id of the "Id" column is 1
private void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
    if (e.CellElement.ColumnInfo.Name == "Name")
    {
        if (Convert.ToInt32(e.CellElement.RowInfo.Cells["Id"].Value) == 1)
        {
            e.CellElement.Image = Image.FromFile(@"flag_blue.gif");
        }
        else
        {
            e.CellElement.Image = null;
        }
    }
}

I hope this helps, but let me know if you need more information
Richard
0
Geert
Top achievements
Rank 1
answered on 04 Jan 2011, 04:01 PM
Thanks for the reply but this is not a solution. The problem is that each row contains a value of the image which must be shown on that line. With the code given you see that I translate the value to an image. In another function I receive al the possible icons in base 64 format and put them in an imagelist.

With this line of code I search for the correct image:

imageCell.Value = imgListPicto.Images[radGrdDocuments.Rows[e.CellElement.RowIndex].Cells["colIconType"].Value.ToString()];

And then I do need the rowindex to search for the value of the picture. 


0
Richard Slade
Top achievements
Rank 2
answered on 04 Jan 2011, 04:10 PM
Hello,

If you can provide a small sample project, posted using the Format Code block, I will alter this for you.
Regards,
Richard
0
Geert
Top achievements
Rank 1
answered on 04 Jan 2011, 04:31 PM
Hello Richard,

How can I upload them? I can only upload images...

Greetz
0
Richard Slade
Top achievements
Rank 2
answered on 04 Jan 2011, 04:35 PM
Hi,

You can't upload a project, but if you just add a samlple section of code, the same way you did with your first sample, I'll be happy to take a look for you.
Thanks
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 05 Jan 2011, 08:54 AM
Hello guys,

I would suggest two different alternatives to this, the easiest one being just storing the RowIndex in the RowInfo.Tag property on DataBindingComplete event and then just using that one, like so:
void radGridView1_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
{
    foreach (var row in radGridView1.Rows)
    {
        row.Tag = row.Index;
    }
}
 
void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
    if (e.CellElement.RowInfo.Tag == null)
    {
        return;
    }
 
    var rowIndex = Convert.ToInt32(e.CellElement.RowInfo.Tag);
 
    if (e.ColumnIndex == 0)
    {
            if ((radGrdDocuments.Rows[rowIndex].Cells["colType"].Value.ToString() == "1"))
            {
                GridViewCellInfo sizeCell = this.radGrdDocuments.Rows[rowIndex].Cells[e.CellElement.ColumnIndex];
                radGrdDocuments.CellFormatting -= new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
                sizeCell.Value = ConvertSizeToString(Convert.ToInt32(radGrdDocuments.Rows[rowIndex].Cells["colActualSize"].Value));
                radGrdDocuments.CellFormatting += new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
            }
    }
    else if (e.CellElement.ColumnIndex == 2)
    {
            GridViewCellInfo imageCell = this.radGrdDocuments.Rows[rowIndex].Cells[e.CellElement.ColumnIndex];
            radGrdDocuments.CellFormatting -= new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
            imageCell.Value = imgListPicto.Images[radGrdDocuments.Rows[rowIndex].Cells["colIconType"].Value.ToString()];
            radGrdDocuments.CellFormatting += new CellFormattingEventHandler(this.radGrdDocuments_CellFormatting);
    }
}

The downside of using this is that if you are allowing adding and removal of rows you will have to recalculate the tags. Another option would be to just use the underlying data source to get the index of the Row's DataBoundItem.

Please let me know if this is ok for you.

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Geert
Top achievements
Rank 1
answered on 05 Jan 2011, 10:36 AM
Thanks guys for the great support!

Now I have found a better solution, I deleted the cellFormatting event and used the Databoundcomplete event for searching my icons and filesize. This is my code:
private void radGrdDocuments_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
       {
           int i = 0;
             
           if (radGrdDocuments.Rows.Count > 0)
           {
               DataView dtSource = (DataView)radGrdDocuments.DataSource;
               foreach (var row in radGrdDocuments.Rows)
               {
                   row.Tag = i;
                   GridViewCellInfo imageCell = this.radGrdDocuments.Rows[i].Cells[2];
                   imageCell.Value = imgListPicto.Images[dtSource[i]["iconType"].ToString()];
                   if (dtSource.Table.Columns["filecheck"] != null)
                   {
                       if ((dtSource[i]["filecheck"].ToString() == "1"))
                       {
                           GridViewCellInfo sizeCell = this.radGrdDocuments.Rows[i].Cells[6];
                           sizeCell.Value = ConvertSizeToString(Convert.ToInt32(dtSource[i]["size"].ToString()));
                       }
                   }
                   i++;
               }
           }
       }
0
Richard Slade
Top achievements
Rank 2
answered on 05 Jan 2011, 10:59 AM
Glad you found a solution. May I also suggest wrapping your ForEach statement in
this.radGridView1.BeginUpdate();
foreach (var row in radGridView1.Rows)
{
   // stuff here
}
this.radGridView1.EndUpdate();
as this will greatly speed up the looping through the rows.
Hope this helps
Richard
Tags
GridView
Asked by
Geert
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Geert
Top achievements
Rank 1
Emanuel Varga
Top achievements
Rank 1
Share this question
or