I'm writing a Windows Forms program. I'm fairly new to linq. I want to order a list of objects in memory. The objects are of class Ctrl (and represent controls on the screen). They have properties which include: CtrlID, Name, X, Y, TabIndex. TabIndex may be zero for a lot of the controls, so I want to order them by TabIndex, Y, X and then run through them setting the TabIndex from one, incrementing, so it is contiguous.
The code I am using is this:
int i;
Ctrl oCtrl = null;
Debug.WriteLine("Before");
for (i = 0; i < _ctrls.Count; i++)
{
oCtrl = _ctrls[i];
Debug.WriteLine(string.Format("{0},ID:{1}: Name:{2}, TabIndex:{3}, X:{4}, Y:{5} ", i.ToString(), oCtrl.CtrlID, oCtrl.Name, oCtrl.TabIndex.ToString(), oCtrl.X, oCtrl.Y));
}
var ctrls = from ctrl in _ctrls.Items
orderby ctrl.TabIndex, ctrl.Y, ctrl.X
select ctrl;
Debug.WriteLine("After");
for (i = 0; i < ctrls.Count(); i++)
{
oCtrl = ctrls.ElementAt(i);
Debug.WriteLine(string.Format("{0},ID:{1}: Name:{2}, TabIndex:{3}, X:{4}, Y:{5} ", i.ToString(), oCtrl.CtrlID, oCtrl.Name, oCtrl.TabIndex.ToString(), oCtrl.X, oCtrl.Y));
oCtrl.TabIndex = i + 1; // cos they're one-based
}
And the results I get in the Output window are these:
0,ID:125: Name:cmd, TabIndex:0, X:124, Y:12
1,ID:126: Name:chk, TabIndex:0, X:124, Y:36
2,ID:127: Name:db, TabIndex:0, X:124, Y:60
3,ID:128: Name:LABEL1, TabIndex:0, X:8, Y:64
4,ID:129: Name:LABEL2, TabIndex:0, X:8, Y:88
5,ID:130: Name:nf, TabIndex:0, X:124, Y:84
6,ID:131: Name:ni, TabIndex:0, X:124, Y:108
7,ID:132: Name:LABEL3, TabIndex:0, X:8, Y:112
8,ID:133: Name:sc, TabIndex:0, X:124, Y:132
9,ID:134: Name:LABEL4, TabIndex:0, X:8, Y:136
10,ID:135: Name:sv, TabIndex:0, X:124, Y:156
11,ID:136: Name:LABEL5, TabIndex:0, X:8, Y:160
12,ID:137: Name:LABEL6, TabIndex:0, X:8, Y:292
13,ID:138: Name:txt, TabIndex:0, X:124, Y:288
14,ID:139: Name:LABEL7, TabIndex:0, X:8, Y:40
15,ID:140: Name:LABEL8, TabIndex:0, X:8, Y:16
After
0,ID:125: Name:cmd, TabIndex:0, X:124, Y:12
1,ID:126: Name:chk, TabIndex:0, X:124, Y:36
2,ID:127: Name:db, TabIndex:0, X:124, Y:60
3,ID:130: Name:nf, TabIndex:0, X:124, Y:84
4,ID:131: Name:ni, TabIndex:0, X:124, Y:108
5,ID:133: Name:sc, TabIndex:0, X:124, Y:132
6,ID:135: Name:sv, TabIndex:0, X:124, Y:156
7,ID:138: Name:txt, TabIndex:0, X:124, Y:288
8,ID:125: Name:cmd, TabIndex:1, X:124, Y:12
9,ID:127: Name:db, TabIndex:3, X:124, Y:60
10,ID:131: Name:ni, TabIndex:5, X:124, Y:108
11,ID:135: Name:sv, TabIndex:7, X:124, Y:156
12,ID:125: Name:cmd, TabIndex:9, X:124, Y:12
13,ID:131: Name:ni, TabIndex:11, X:124, Y:108
14,ID:125: Name:cmd, TabIndex:13, X:124, Y:12
15,ID:125: Name:cmd, TabIndex:15, X:124, Y:12
All the controls named "LABEL..." are missing, and some of the rest are duplicated. The values where TabIndex showing as > 0 is due to the fact that I am setting its value after printing the output, but because some of the objects are referenced twice, the new value is showing the second time round. If I comment out the orderby clause so it is a straight select, I get the data back in the order it is currently in, without duplicates or items missing.
So:
- why am I missing objects?
- why have I got duplicate objects?
- how do I get orderby to do what I am expecting?
Thanks for any help provided.