Thursday, February 17, 2011

Counting the number of unique image occurences in a DataGridViewImageColumn

In a DataGridView bound to a DataView, where cells in a column will contain one of two images from an ImageList (e.g. a green 'online' image or a red 'offline' image), how can you sum the number of occurences of each image when iterating through the DataGridView's rows?

The Value and FormattedValue properties of DataGridViewImageCell return different references even though the entries in the underlying DataTable were created by referencing the same Image from the ImageList.

So rather than it counting 4 occurences of 'online' and 6 occurences of 'offline', I'm getting 10 occurences of alledgedly different images.

From stackoverflow
  • Given the description, the best I can suggest is to manually track the image key/index in the .Tag of the cell, and then run your distinct count on the .Tag. Alternatively, if you also have the data in a list/collection, count the data from the original source.

    [update following reply] Since the data is data-bound, you should be able to iterate the .Rows of the DataGridView, obtaining the .DataBoundItem of each. Then for each underlying object, you should be able to obtain the actual property value using TypeDescriptor:

            string propName = col.DataPropertyName;
            // could also be a dictionary/hashset etc
            // could be typed if you know the type
            List<object> values = new List<object>();
            foreach(DataGridViewRow row in dgv.Rows)
            {
                object obj = row.DataBoundItem;
                // could be typed (via cast) if you know the type
                object val = TypeDescriptor.GetProperties(obj)[propName].GetValue(obj);
                if (!values.Contains(val))
                {
                    values.Add(val);
                }
            }
    

    That any help?

    frou : Hi Marc - thanks for the reply. At what point would you assign to the Tag property of the cell seeing as the DataGridView is data bound and auto-populates itself?
    frou : + The DataGridView is showing a subset of the entire DataTable (using DataView.RowFilter) and within that I only want to count within the currently highlighted rows (MultiSelect). So back-tracking to the original data source seems difficult
    Marc Gravell : I'll update to indicate...
    frou : It looks like the bitmaps must be duplicated in memory for every row because using your approach, the bitmap references that come back are different for every row, even if they are using the same image from the image list.
    frou : + I'll have to rethink this because I don't want to end up doing pixel level equality tests! Thanks for your answer though, it definitely seems like it should work. I wish I could give you more points but I can't mark it as the answer

0 comments:

Post a Comment