Forum: PC-Programmierung [c#] COM-Port-Auswahl in ComboBox alphabetisch sortierten / Dateien sortieren


von Rainer S. (cubi)


Lesenswert?

Hallo


Ich habe eine ComboBox in der ich die verfügbaren COM-Ports 
(WinXP/.NET/C#) zur Auswahl darstellen kann.
1
comboBox1.ItemsSource =  SerialPort1.GetPortNames();

Zum alphabetischen Sortieren habe ich jetzt ein List-Objekt dazwischen 
geschaltet in dem ich die Sortierung vornehme.

1
List <string>  list_comport = new List <string> (SerialPort.GetPortNames());
2
list_comport.Sort();
3
4
comboBox1.ItemsSource = list_comport;



Das Sortieren funktioniert jetzt zwar nach den typischen 
Sortier-Algorithmus, aber die Ausgabe ist diese:

COM1
COM18
COM19
COM2
COM20
COM4
COM5



Wie ist es diese Sortier-Ausgabe herzustellen ?

COM1
COM2
COM4
COM5
COM18
COM19
COM20


Bei Datei-Listen u.ä. wird dieses Problem auch bestehen.

Ich bin absolut neu auf dem Feld der Programmierung und habe kaum 
Erfahrung.
Wenn jemand ein paar Hinweise geben könnte, wie man dies 
bewerkstellingen könnte, würde ich mich sehr freuen.

Gruß


Cubi

von Chris .. (dechavue)


Lesenswert?

Gibs sicher schönere Lösungen (die hier funktioniert nur wenn 3 gleiche 
Zeichen gefolgt von der Nummer nach der sortiert werden soll vorhanden 
sind) aber für Com-Ports sollte es ausreichend sein.
1
List<string> ports = new List<string>() {
2
  "COM1",
3
  "COM18",
4
  "COM2",
5
  "COM19",
6
  "COM20",
7
  "COM4",
8
  "COM5"};
9
10
ports.Sort(new Comparison<string>(delegate(string a, string b) {
11
  return int.Parse(a.Substring(3)) -
12
         int.Parse(b.Substring(3));
13
}));

von Rainer S. (cubi)


Lesenswert?

" Wie Geil !!!!!! "

Sorry ,  das war mein Ausspruch nachdem es funkionierte.

Vielen Dank für den Code dechavue.

Ich habe den Code noch nicht richtig verstanden, aber diese Zeilen 
zeigen mir , daß  ich die Kapitel über parse noch einmal durchlesen muß.
//



Im Internet habe ich nur solche Lösungen gefunden in denen geraten wurde
führende Nullen zu verwenden.
Wenn jemand noch eine Universallösung, die mit allen Zeichenketten zu 
recht kommen würde kennt, nur her damit.

Gruß

Cubi

von Chris .. (dechavue)


Lesenswert?

Etwas verständlicher sieht das Ganze wahrscheinlich in der Form aus:
1
List<string> ports = new List<string>() {
2
  "COM1",
3
  "COM18",
4
  "COM2",
5
  "COM19",
6
  "COM20",
7
  "COM4",
8
  "COM5"};
9
10
ports.Sort(new Comparison<string>( ComparePortStrings  ));
11
12
...
13
14
15
16
//returns:
17
// a  < b --> return < 0
18
// a == b --> return = 0
19
// a  > b --> return > 0 
20
private int ComparePortStrings (string a, string b) {
21
  return int.Parse(a.Substring(3)) -
22
         int.Parse(b.Substring(3));
23
}

Man kann der Sort-Methode eine Methode die zum Vergleichen verwendet 
wird mitgeben (ähnlich einem Prädikat/Funktor in der STL in C++)

Ist vom Prinzip genau das Gleiche wie die erste Variante, nur dass in 
der vorherigen Variante eine anonyme Methode verwendet wurde.

Das Parse macht nur aus dem String (hier ab Index 3) einen Integer. 
Durch die Subtraktion erhält man gleich das passende Ergebnis für die 
Compare-Methode.

Hier noch eine etwas allgemeinere Variante der Compare-Methode:
1
 
2
Regex rexNum =new Regex(@"(?<Text>^.+?)(?<Num>\d+)?(?<Ext>\.[^\.]+)?$", RegexOptions.Compiled);
3
Match mA = rexNum.Match(a);
4
Match mB = rexNum.Match(b);
5
6
if(mA.Success && mB.Success &&
7
   mA.Groups["Num"].Success && mB.Groups["Num"].Success &&
8
   mA.Groups["Text"].Value == mB.Groups["Text"].Value]) {
9
    return int.Parse(mA.Groups["Num"].Value) -
10
           int.Parse(mB.Groups["Num"].Value);
11
}
12
return a.CompareTo(b);
Hier wir wenn die Nummer als letztes (vor einer eventuellen 
Dateierweiterung) steht und der Text davor gleich ist die Nummer 
verglichen, sonst der Text nach dem Standard-Stringvergleich.

Aber Achtung, die Neue Variante ist großteils ungetestet.

von Rainer S. (cubi)


Lesenswert?

Vielen Dank für Deine Mühe Chris.

Diese Codes helfen mir sehr weiter.

Gruß


Cubi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.