Search code examples
c#.netdatagridviewdatagridviewcolumngridview-sorting

how to sort the datagridview column Got an error : Argument NUll Exception Was Unhandled


I am binding the data grid view by using the following linq to entity framework query by using the following code..

        private void EquipmentFinder_Load(object sender, EventArgs e)
    {
        SetupCategories();
        productgridview.RowTemplate.Height = 130;
        var products = from prods in axe.product1
                       select new
                       {
                           productid = prods.product_Id,   //0                            
                           productnam =  prods.product_Name, //1
                           productimage = prods.product_Image, //2
                           productprice = prods.product_Price,//3
                           productdescr = prods.product_Description, //4

                       };

        productbindingsource.DataSource = products;
        productgridview.DataSource = productbindingsource;          
        productgridview.Columns[0].Visible = false;
        productgridview.Columns[4].Visible = false;
    }  

I have got the columns product id , product image ,product name ,product desription,product price..

i have made some of the columns are not visible for the purpose of client ..

now i want to sort the columns by clicking on the column header ....

Note: here the product.image is stored as byte of arrays in database ....

i dont know how to compare the bytes and sorting like that....

would any one pls help on this one......

many thanks...

MODIFIED CODE:

          private void productgridview_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
       DataGridViewColumn newcolumn =  productgridview.Columns.GetColumnCount(DataGridViewElementStates.Selected) == 1 ? productgridview.SelectedColumns[0] : null;
       DataGridViewColumn oldColumn = productgridview.SortedColumn;
       ListSortDirection direction;

       if (oldColumn != null)
       {
           // Sort the same column again, reversing the SortOrder.
           if (oldColumn == newcolumn &&
               productgridview.SortOrder == SortOrder.Ascending)
           {
               direction = ListSortDirection.Descending;
           }
           else
           {
               // Sort a new column and remove the old SortGlyph.
               direction = ListSortDirection.Ascending;
               oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
           }
       }
       else
       {
           direction = ListSortDirection.Ascending;
       }


           productgridview.Sort(newcolumn, direction);
           newcolumn.HeaderCell.SortGlyphDirection =
               direction == ListSortDirection.Ascending ?
               SortOrder.Ascending : SortOrder.Descending;



    }

got An error: Argument NUll Exception Was Unhandled ..

           Value cannot be null.
           Parameter name: dataGridViewColumn

would any one help on this....


Solution

  • I have tried the following code and it works, I don't have images so I used empty column. The code is bit long because I had to implement BindingList<T> to implement sorting. You can read more about the implementation of BindingList<T> in this answer and here. You can find more about AutoPoco here.

    using AutoPoco.Engine;
    using AutoPoco;
    using AutoPoco.DataSources;
    
    namespace GridViewSorting
    {
        public partial class TestForm : Form
        {
            public TestForm()
            {
                InitializeComponent();
            }
    
            private void TestForm_Load(object sender, EventArgs e)
            {
                LoadGridData();
            }
    
            private void gv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
            {
                var newcolumn = gv.Columns[e.ColumnIndex];
                var showColumn = newcolumn;
    
                ListSortDirection direction;
                var sortedColumn = gv.SortedColumn;
    
                var sd = sortedColumn==null? SortOrder.None:sortedColumn.HeaderCell.SortGlyphDirection;
    
                if (sortedColumn == newcolumn && sd == gv.SortOrder)
                    return;
    
                if (sd == SortOrder.Descending || sd == SortOrder.None)
                {
                    sd = SortOrder.Ascending;
                    direction = ListSortDirection.Ascending;
                }
                else
                {
                    sd = SortOrder.Descending;
                    direction = ListSortDirection.Descending;
                }
    
                //now the fun begins, suppose this is image column and you want to 
                //sort based on product name when product image column header
                //is clicked.
    
                if (newcolumn.HeaderText == "ProductImage")//check if image column
                {
                    newcolumn = gv.Columns["ProductName"];//sort on product names
                }
    
                gv.Sort(newcolumn, direction);
                newcolumn.HeaderCell.SortGlyphDirection = SortOrder.None;
                showColumn.HeaderCell.SortGlyphDirection = sd;//change sort indicator on clicked column
            }
    
            private void LoadGridData()
            {
                IGenerationSessionFactory factory = AutoPocoContainer.Configure(x =>
                {
                    x.Conventions(c => { c.UseDefaultConventions(); });
                    x.AddFromAssemblyContainingType<SimpleProduct>();
    
                    x.Include<SimpleProduct>()
                        .Setup(c => c.ProductName).Use<FirstNameSource>()
                        .Setup(c => c.Id).Use<IntegerIdSource>()
                        .Setup(c => c.ProductDescription).Use<RandomStringSource>(5, 20);
                });
    
                var session = factory.CreateSession();
                var r = new Random(234234);
                var rn = r.Next(5, 100);
                IList<SimpleProduct> products = session.List<SimpleProduct>(25)
                    .Impose(x => x.Price, r.Next() * rn)
                    .Get();
                var bl = new ProductList();
    
                foreach (var i in products)
                {
                    bl.Add(i);
                }
    
                gv.DataSource = bl;
            }
        }
    
        public class ProductList : SortableProductList<SimpleProduct>
        {
            protected override Comparison<SimpleProduct> GetComparer(PropertyDescriptor prop)
            {
                Comparison<SimpleProduct> comparer;
                switch (prop.Name)
                {
                    case "Id":
                        comparer = new Comparison<SimpleProduct>(delegate(SimpleProduct x, SimpleProduct y)
                        {
                            if (x != null)
                                if (y != null)
                                    return (x.Id.CompareTo(y.Id));
                                else
                                    return 1;
                            else if (y != null)
                                return -1;
                            else
                                return 0;
                        });
                        break;
                    case "ProductName":
                        comparer = new Comparison<SimpleProduct>(delegate(SimpleProduct x, SimpleProduct y)
                        {
                            if (x != null)
                                if (y != null)
                                    return (x.ProductName.CompareTo(y.ProductName));
                                else
                                    return 1;
                            else if (y != null)
                                return -1;
                            else
                                return 0;
                        });
                        break;
                    case "ProductDescription":
                        comparer = new Comparison<SimpleProduct>(delegate(SimpleProduct x, SimpleProduct y)
                        {
                            if (x != null)
                                if (y != null)
                                    return (x.ProductDescription.CompareTo(y.ProductDescription));
                                else
                                    return 1;
                            else if (y != null)
                                return -1;
                            else
                                return 0;
                        });
                        break;
                    case "Price":
                        comparer = new Comparison<SimpleProduct>(delegate(SimpleProduct x, SimpleProduct y)
                        {
                            if (x != null)
                                if (y != null)
                                    return (x.Price.CompareTo(y.Price));
                                else
                                    return 1;
                            else if (y != null)
                                return -1;
                            else
                                return 0;
                        });
                        break;
                    default:
                        comparer = new Comparison<SimpleProduct>((x, y) =>
                        {
                            if (x != null && y != null)
                                return x.GetHashCode().CompareTo(y.GetHashCode());
                            return 0;
                        });
                        break;
                }
                return comparer;
            }
        }
    
        public abstract class SortableProductList<T> : BindingList<T>
        {
            protected override bool SupportsSortingCore{get{return true;}}
    
            protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
            {
                if (prop.PropertyType.GetInterface("IComparable") == null)return;
                var itemsList = (List<T>)this.Items;
    
                Comparison<T> comparer = GetComparer(prop);
                itemsList.Sort(comparer);
                if (direction == ListSortDirection.Descending) itemsList.Reverse();
            }
    
            protected abstract Comparison<T> GetComparer(PropertyDescriptor prop);
        }
    
        public class SimpleProduct
        {
            public int Id { get; set; }
            public string ProductName { get; set; }
            public decimal Price { get; set; }
            public string ProductImage { get; set; }
            public string ProductDescription { get; set; }
        }
    }
    

    You will get your thing in gv_ColumnHeaderMouseClick function.