M.Bouabdallah
M.Bouabdallah

Reputation: 772

Grouping list before added to the GridView

I have this code that added items to list

private void GetParts(bool AllObjects)
{
    ModelObjectEnumerator ImportModel = null;
    List<Beam> parts = new List<Beam>();
    if (AllObjects)
    {
        ImportModel = MyModel.GetModelObjectSelector().GetAllObjectsWithType(ModelObject.ModelObjectEnum.BEAM);
    }
    else
    {
        TSMUI.ModelObjectSelector GetSelectedObjects = new TSMUI.ModelObjectSelector();
        ImportModel = GetSelectedObjects.GetSelectedObjects();
    }

    while (ImportModel.MoveNext())
    {
        Beam ThisBeam = ImportModel.Current as Beam;

        if (ThisBeam != null)
        {
            parts.Add(ThisBeam);

        }
    }

After that I'm supposed to iterate through all items to added to the GridView like this

for (int i = 0; i < parts.Count; i++)
{ 
        DataRow row = dt.NewRow();

        var partMark = string.Empty;
        parts[i].GetReportProperty("PART_POS", ref partMark);
        row[0] = partMark;
        row[1] = parts[i].Profile.ProfileString;
        int num = 0;
        row[2] = parts[i].GetReportProperty("MODEL_TOTAL", ref num);
        double length = 0;
        parts[i].GetReportProperty("LENGTH", ref length);
        row[3] = length;
        dt.Rows.Add(row);
}

but before I do that I want to group items using (partMark ,length ) and Sum(num ).

How can I do that?Thanks in advance.

Upvotes: 0

Views: 408

Answers (1)

Scope Creep
Scope Creep

Reputation: 565

It sounds like you are wanting to do is the GROUP your items by partMark and length, then to SORT the grouped items in the list by the SUM of num. I would recommend using LINQ to do the grouping/sorting.

When using the GroupBy method of IEnumerable the return Type is IEnumerable>. This means you cannot group a list of items back into itself, which is what I was trying to do in the first attempt at answering this.

To resolve this issue, I created a class called GroupedPart that has the same fields as Part, but adds a "Parts" property to contain the List of Part objects that are grouped together by PartLength and PartMark.

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public class Part
    {
        public String Name {get; set;}
        public double PartLength {get; set;}
        public double PartMark {get; set;}
        public int Number {get; set;}

        public Part(String partName, double length, double mark, int value)
        {
            Name = partName;
            PartLength = length;
            PartMark = mark;
            Number = value;
        }
    }

    public class GroupedPart
    {
        public String Name => Parts.First().Name;
        public double PartLength { get; set; }
        public double PartMark { get; set; }
        public int Number { get; set; }
        public List<Part> Parts { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

Then, with the backing objects created, you can use this code to group and order them. This second code block is merely is a Form object with a DataGridView on it so that the grouped and sorted results are visible.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private List<Part> parts;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            parts = new List<Part>();
            parts.Add(new Part("Hammer #1", 1, 5, 3));
            parts.Add(new Part("Hammer #2", 1, 5, 4));
            parts.Add(new Part("Hammer #3", 1, 1, 6));

            parts.Add(new Part("Nail #1", 7, 10, 14));
            parts.Add(new Part("Nail #2", 8, 10, 13));
            parts.Add(new Part("Nail #3", 9, 10, 15));

            parts.Add(new Part("Screw", 16, 17, 18));

            var results = parts.GroupBy(part => new {part.PartLength, part.PartMark})
                .Select(grouped => new GroupedPart()
                {
                    PartLength = grouped.Key.PartLength,
                    PartMark = grouped.Key.PartMark,
                    Parts = grouped.ToList()
                })
                .OrderBy(p => p.Parts.Sum(part => part.Number));

            List<GroupedPart> groupedParts = results.ToList();

            dataGridView1.DataSource = groupedParts;
        }
    }
}

If you run this code, you will see Hammer #1 and Hammer #2 grouped together because they have the same PartLength and PartMark. The other parts are grouped by themselves because they have unique PartLength/PartMark combinations. Additionally, you will see that the "Nail" parts (Nail #1, Nail #2, Nail #3) are reordered (Nail #2, Nail #1, Nail #3) because their assigned "Number" property. If you comment out the OrderBy line of code, you will see that the Hammer objects remained grouped together, but that the Nail objects revert to their original ordering.

Upvotes: 1

Related Questions