chrisb
chrisb

Reputation: 323

how to get Datagridview selected cells in ordered by their column

I have a table with columns c1 .. c4 and with a row containing data such as

c1 c2 c3 c4

[CAN][YOU][HELP][ME]

Multiselect is on. When I get datagridview.SelectedCells then they will be in the list in order of when they were selected. E.g. I select HELP and then YOU the list will be HELP followed by YOU. However I need a list to show YOU,HELP because YOU is from a column before HELP. If I would select YOU,HELP,CAN in that order then the list should be CAN,YOU,HELP because CAN is in c1, YOU in c2 and HELP in c3.

How can I do this? Thank you for your help.

Chris

Hi here is the code. The order of the selected cell list depends on how you select them - e.g. start left to right or vice versa. As you can see from the code, I have found a workaround. The OrderBy idea is much more elegant but I believe it only works for Rows and not for cells.

private void attribute_treeview_DragDrop(object sender, DragEventArgs e) { // dropped item from either datagridview into treeview

        if (e.Data.GetDataPresent(typeof(List<string>)))
        {
            // Determine which category the item was draged to
            Point p = attribute_treeview.PointToClient(new Point(e.X, e.Y));
            TreeNode destinationNode = attribute_treeview.GetNodeAt(p);

            // sort selected cells based on position in productname
            var selected_cells = e.Data.GetData(typeof(List<string>)) as List<string>;
            SortedDictionary<int, string> orderedcellcontents = new SortedDictionary<int, string>();

            ProductItem pitem = new ProductItem((BsonDocument)productlist.SelectedItems[0].Tag);

            foreach (var element in selected_cells)
            {
                int pos = Array.IndexOf(pitem.tokens, element);
                if (!orderedcellcontents.ContainsKey(pos))
                    orderedcellcontents.Add(pos, element);
            }

            if (PopulateTreeview(destinationNode, orderedcellcontents.Values.ToList<string>())) 
            {
                dictionary_haschanged = true;
                destinationNode.Expand();
            }

        }

Upvotes: 1

Views: 3876

Answers (2)

zerox981
zerox981

Reputation: 366

I think this is much easier/cleaner/shorter.

datagridview.SelectedCells
    .Cast<DataGridViewCell>()
    .OrderBy(c=>c.ColumnIndex)

Upvotes: 3

DieterC
DieterC

Reputation: 81

you can try using linq to order them on index

var ordered = datagridview.SelectedCells.OrderBy(c=>c.Index)

Edit 1: so the above doesn't seem to work. Below I've created a small forms app to test. The app consists of a form with a datagridview on it, a button and a textbox. Clicking the button will display the selectedcells in their correct order in the textbox. See the button1_click event for the sorting.

Forms1.cs

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        var data = new List<Data>();
        data.Add(new Data { A = "CAN", B = "YOU", C = "HELP", D = "ME" });
        data.Add(new Data { A = "CAN", B = "YOU", C = "HELP", D = "ME" });
        data.Add(new Data { A = "CAN", B = "YOU", C = "HELP", D = "ME" });
        data.Add(new Data { A = "CAN", B = "YOU", C = "HELP", D = "ME" });
        dataGridView1.DataSource = data;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var selectedCells = dataGridView1.SelectedCells;
        var array = new DataGridViewCell[selectedCells.Count];

        selectedCells.CopyTo(array,0);
        var sorted = array.OrderBy(c => c.ColumnIndex);

        var s = string.Join(Environment.NewLine, sorted.Select(c => c.Value));
        textBox1.Text = s;
    }
}

public class Data
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
}

Copying the cells to a DataGridViewCell array will let you sort it on the index.

Upvotes: 2

Related Questions