Search code examples
c#visual-studiodatagridviewdesktop-application

How do i update the sorted column back into the datagridview and also changing its respective items


Image of the application

So there are 4 columns ID,ItemName,ItemCategory and PriceAmount What i want to do is sort the price amount by clicking the dropdown menu and i took out the price amount added it in an arrray and then sorted it using bubble sort but i am having a hard time finding out how do i update the datagridview as per the price amount and changing its respective columns too any help? This is what i did

        int[] price = new int[dataGridView1.Rows.Count];
        for (int i = 0; i < dataGridView1.Rows.Count; i++)
        {
            price[i] = Convert.ToInt32(dataGridView1.Rows[i].Cells[3].Value);

            for (int j = 0; j < price.Length; j++)
            {
                Console.WriteLine(price[j]);
            }
        }



        int temp;

        for (int j = 0; j <= price.Length - 2; j++)
        {
            for (int i = 0; i <= price.Length - 2; i++)
            {
                if (price[i] > price[i + 1])
                {
                    temp = price[i + 1];
                    price[i + 1] = price[i];
                    price[i] = temp;
                }
            }

        }

        foreach(int sortedArray in price)
        {
            Console.Write(sortedArray + " ");
            Console.ReadLine();
        }

here is the code of the browse button

   private void browseBtn_Click(object sender, EventArgs e)
        {
        OpenFileDialog dialog = new OpenFileDialog();

        dialog.Filter = "Files(*.txt, *.csv)|*.txt;*.csv|All Files (*.*) |*.*";

        DialogResult result = dialog.ShowDialog();
        if (result == DialogResult.OK)
        {
            pathTextBox.Text = dialog.FileName;

        }

        if(pathTextBox.Text.Length>0)
        {
            importBtn.Enabled = true;
        }

    }

then it grabs the location of the .csv file and then adds in the textbox and then the insert button imports it

      private void importBtn_Click(object sender, EventArgs e)
    {

        string value = pathTextBox.Text;
        importCSVDataFile(value);
        pathTextBox.Text = "";

    }

Code of importCSVDataFile

    private void importCSVDataFile(string filepath)
    {
        try
        {
            TextFieldParser csvreader = new TextFieldParser(filepath);

            csvreader.SetDelimiters(new string[] { "," });

            csvreader.ReadFields();
            //int row_count = 0;
            while (!csvreader.EndOfData)
            {
                string[] fielddata = csvreader.ReadFields();

                dataGridView1.Rows.Add();

                for (int i = 0; i < fielddata.Length; i++)
                {

                    dataGridView1.Rows[row_count].Cells[i].Value = fielddata[i];
                }
                row_count++;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Import CSV File", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

I was performing a insert and update work with this

     private void insertBtn_Click(object sender, EventArgs e)
    {

        string id = idTextBox.Text;
        string itemName = itemNameTextBox.Text;
        string itemCategory = categoryTextBox.Text;
        string itemPrice = priceTextBox.Text;

        if (this.status)
        {
            dataGridView1.Rows[this.row].Cells[0].Value = id;
            dataGridView1.Rows[this.row].Cells[1].Value = itemName;
            dataGridView1.Rows[this.row].Cells[2].Value = itemCategory;
            dataGridView1.Rows[this.row].Cells[3].Value = itemPrice;
            this.insertBtn.Text = "Save";
            dataGridView1.Rows[this.row].Selected = true;

            MessageBox.Show("Existing Record Updated");
        }
        else
        {
            int count = dataGridView1.Rows.Count;
            dataGridView1.Rows[count].Cells[0].Value = id;
            dataGridView1.Rows[count].Cells[1].Value = itemName;
            dataGridView1.Rows[count].Cells[2].Value = itemCategory;
            dataGridView1.Rows[count].Cells[3].Value = itemPrice;
            dataGridView1.Rows[count].Selected = true;

            MessageBox.Show("New Record Saved!!");
            row_count++;


        }
        itemNameTextBox.Text = "";
        categoryTextBox.Text = "";
        priceTextBox.Text = "";
        this.status = false;
        this.row = 0;

    }

Sort Algorithm of Bubble Sort for itemName

    private void sortByItem()
    {
        int rows = dataGridView1.Rows.Count;
        for (int i = 0; i < rows; i++)
        {
            for (int j = 1; j < rows; j++)
            {
                string val1 = Convert.ToString(dataGridView1.Rows[j - 1].Cells[0].Value);
                string val2 = Convert.ToString(dataGridView1.Rows[j].Cells[0].Value);
                if (string.Compare(val1, val2) > 0)
                {
                    for (int a = 0; a < this.dataGridView1.Columns.Count; a++)
                    {
                        object temp = this.dataGridView1[a, j - 1].Value;

                        this.dataGridView1[a, j - 1].Value = this.dataGridView1[a, j].Value;
                        this.dataGridView1[a, j].Value = temp;
                    }
                }
            }
        }

Solution

  • The way you are binding data in the gridview is not right. That way you can not achieve functionality of sorting GridView.

    What you need is a class which represents the data which are loading in the gridview.

    Let say you have a product class as following.

    public class Product
    {
        public int ID { get; set; }
    
        public string Name { get; set; }
    
        public string Category { get; set; }
    
        public double Price { get; set; }
    }
    

    Now you have data of multiple products in the file so you need to create a list of products and initialize it in the form as following.

    public partial class Form1 : Form
    {
        private List<Product> products;
        public Form1()
        {
            products = new List<Product>();
            InitializeComponent();
        }
    }
    

    Now method importCSVDataFile needs to be changed as following to load data from the file and populate the list and bind it to the grid view.

    private void importCSVDataFile(string filepath)
        {
            try
            {
                TextFieldParser csvreader = new TextFieldParser(filepath);
    
                csvreader.SetDelimiters(new string[] { "," });
    
                csvreader.ReadFields();
                while (!csvreader.EndOfData)
                {
                    string[] fielddata = csvreader.ReadFields();
    
                    var product = new Product();
                    product.ID = Convert.ToInt32(fielddata[0]);
                    product.Name = fielddata[1];
                    product.Category = fielddata[2];
                    product.Price = Convert.ToDouble(fielddata[3]);
    
                    products.Add(product);
                }
    
                dataGridView1.DataSource = products;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Import CSV File", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    

    Once you have data displayed in the grid, you need to change sorting code as following.

    Let say you have combobox1 which has column names listed to sort the gridview. So code of combobox1's SelectedIndexChanged event will be as following.

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedItem != null)
            {
                var selectedColumnName = comboBox1.SelectedItem as string;
    
                switch (selectedColumnName)
                {
                    case "ID":
                        dataGridView1.DataSource = products.OrderBy(product => product.ID).ToList();
                        break;
                    case "Name":
                        dataGridView1.DataSource = products.OrderBy(product => product.Name).ToList();
                        break;
                    case "Category":
                        dataGridView1.DataSource = products.OrderBy(product => product.Category).ToList();
                        break;
                    case "Price":
                        dataGridView1.DataSource = products.OrderBy(product => product.Price).ToList();
                        break;
                }
            }
        }
    

    To add new products to the gridview you need to create new instance of Product and set its properties and then add it to the list and bind the list to the gridview again.

    public void btnInsert_Click(object sender, EventArgs e)
    {
        var id = Convert.ToInt32(txtId.Text);
    
        var objProduct = products.FirstOrDefault(product => product.ID == id);
    
        if (objProduct == null)
        {
            objProduct = new Product();
            objProduct.ID = id;
            objProduct.Name = txtName.Text;
            objProduct.Category = txtCategory.Text;
            objProduct.Price = Convert.ToDouble(txtPrice.Text);
            products.Add(objProduct);
        }
        else
        {
            objProduct.Name = txtName.Text;
            objProduct.Category = txtCategory.Text;
            objProduct.Price = Convert.ToDouble(txtPrice.Text);
        }
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = products;
    }
    

    I hope this would help you resolve your issue.