Autor Beitrag
Adabei
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Sa 27.09.14 10:46 
Hallo, also ich habe folgendes Problem.

Ich habe eine Liste erstellt, wo alle Daten einer Datenbank drinnen sind, aber ich brauche die Daten einzeln pro Zeile, für das Alter:

also die Datenbank schaut so aus:

ID Name alter
1 albert 10
2 berta 50
3 clown 45
..

Nun habe ich 3 Textboxen, wo in der ersten drinnen stehen soll: berta 50; dann in der zweiten textbox: clown 45 und in der dritten dann: albert 10;
also es soll nach dem alter sortieren.

programmiert habe ich alles mal so, dass alle Daten der Datenbank in der Liste myList drinnen sind, hier der Code dafür:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var myList=new List<Liste>();

                while (m_Reader.Read())
                {
                    string iD = (m_Reader[0].ToString());
                    string name= (m_Reader[1].ToString());
                    string alter= (m_Reader[2].ToString());

                    var Versuch= new Liste()
                    {
                        ID=iD,
                        Name=name,
                        Alter=alter,
                    };
                    myList.Add(Versuch);
                }


dann habe ich auch noch ne Klasse Liste, wo dass drinnen ist:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
public class Liste
    {
        public string ID { get; set; }
        public string Name{ get; set; }
        public string Alter{ get; set; }
    }


aja zur info: habe dass mit anleitungen von hier programmiert(von anderen forenbeiträge, aber jetzt komme ich leider nicht weiter)

also noch mal zusammenfassend: das Problem was ich leider nicht schaffe, ich will es nach dem Alter sortieren, und der name soll aber natürlich automatisch mitspringen mit dem alter, also wenn die liste dann sortiert ist, darf nicht sein dass dann ein alter und der name nicht dazupassen, ich hoffe ihr wisst was ich meine, wenn nicht bitte einfach nochmals nachfragen

lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 27.09.14 11:14 
a.) Bennen die Liste Klasse sinnvoll. Es ist keine Liste sondern irgendeine Klasse die hier zufällig in einer Liste benutzt wird. Ein sinnvollerer Name wäre zum Beispiel Person.
b.) ID und Alter sind keine Strings sondern Zahlen. Also benutzt besser entsprechende Datentypen. Gerade Alter macht dir sonst als string Probleme. Als Text wäre "10" kleiner als "2"!

Zum sortieren gibt es viele Möglichkeiten eine wäre die Sort Methode von List<T>

ausblenden C#-Quelltext
1:
list.Sort((x,y) => x.Alter.CompareTo(y.Alter));					


oder die Extension Methods von LINQ

ausblenden C#-Quelltext
1:
list = list.OrderBy(x => x.Alter).ToList();					


Das funktioniert aber wie gesagt jeweils nur wirklich richtig wenn Alter eine Zahl ist und kein string.

Zu deiner UI solltest du erstmal zeigen/erklären was du bisher hast. Da was mit Textboxen zu versuchen klingt erstmal nicht wirklich zielführend. Es sind doch tabellarische Daten (beliebig viele Personen) da würde sich dann auch ein entsprechendes Control anbieten zum Beispiel ein DataGridView.

Für diesen Beitrag haben gedankt: Adabei
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 27.09.14 11:19 
Hallo,

um die Liste zu sortieren, gibt es die Methode List<T>.Sort(), welche eine Vergleichsmethode entgegennimmt.
In deinem Fall z.B.
ausblenden C#-Quelltext
1:
myList.Sort(SortByAge);					

Und die Methode hat dann diese Implementierung:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
static int SortByAge(Liste x, Liste y) // <- s. mein PS unten!!!
{
  return Comparer<string>.Default.Compare(x.Alter, y.Alter);
  // returns -1 / 0 / 1 // für kleiner, gleich, größer
}

Allerdings ist der Datentyp string für das Alter nicht gut, denn dann würdest du ja alphabetisch sortieren. Besser ist es du legst gleich diese Eigenschaft als int an und benutzt beim Auslesen .ToInt32().

PS: Der Name Liste für einen einzelnen Eintrag ist äußerst ungünstig und verwirrend ;-)

PPS: Ich würde auch das DataGridView zur Anzeige empfehlen.

Für diesen Beitrag haben gedankt: Adabei
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Sa 27.09.14 11:36 
danke für die antworten!!!

dass problem mit string und int habe ich gelöst, habe einfach ConvertToInt32 vor klammer geschrieben und statt string immer int angegeben


ja das mit der Namenswahl ist bei mir als Anfänger wsl sehr schlecht immer, tut mit leid :flehan:

also ich weiß leider nicht wie ich das UI hier reinkopieren kann, deshalb erkläre ich es euch:
ich habe eine klasse namens alter, wo oben steht in einem label: Die drei ältesten Leute hier sind:
dann habe ich eine tbox vor der steht ein label 1 und dort in der tbox soll nun halt berta 50 stehen;
dann ein label 2 und danach eine tbox wo dann drinnen stehen soll clown 45;
ich habe vorher eine andere klasse(form1) in der drinnensteht dass man namen und alter angeben soll und dass wird dann in der datenbank gespeichert die eingegeben daten. habe auch schon probiert, dass mit dem eingegeben wird ohne problem im richtigen gespeichert, also die daten sind in der datenbank vorhanden.

soll ich jetzt gleich die liste sortieren?
wäre es nicht besser zuerst die spalten einzeln zu haben und dann die spalte mit dem alter zu sortieren?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 27.09.14 12:14 
Zitat:
wäre es nicht besser zuerst die spalten einzeln zu haben und dann die spalte mit dem alter zu sortieren?


Nein. Der Gedanke wird dich nicht weiter führen. Das klingt so physisch gedacht. Als wäre es leichter nur ein Feld anstatt einer ganzen Klasse zu sortieren.
Es macht für die Sortierung keinen Unterschied wie groß/komplex das Ding ist was da sortiert wird. Letztlich wird es sich nicht im Speicher bewegen die Liste referenziert die Dinge nur anders.
Und die Klasse auseinanderzureisen nur um irgendwas anhand eines einzelnen Feldes zu machen um die Klasse danach wieder zusammenzusetzen ist ebenfalls nicht hilfreich. Stell die eine Klasse besser als unteilbare Einheit vor. Das Alter existiert nicht alleine es gehört zu einer Person.

Alternativ, da du sagst das die Daten aus einer Datenbank kommen, kannst du das Sortieren auch schon im SQL (Order By) machen. Dann wird dir der DataReader das schon wunschgemäß sortiert liefern und du kannst sortieren im C# Code ignorieren da es das ja dann schon ist.

Wenn du tatsächlich nur 3 Datensätze willst dann kannst du dann auch gleich einfach nur die ersten 3 aus der DB holen und nicht einfach alle um dann doch nur 3 zu benutzen. Um dir bei einem passenden SQL zu helfen solltest du uns aber sagen was für eine DB du verwendest (und wie die Tabelle/Spalten heißen)

Für diesen Beitrag haben gedankt: Adabei
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Sa 27.09.14 12:26 
ok, danke

ich verwende access, aber ich will schon lieber in c# sortieren, schließlich muss ich ja beim programmieren besser werden um nicht dauerhaft hier für euch nervige und laienhafte fragen stellen zu müssen :wink:

du hast mir eh schon einen lösungsansatz gegeben, allerdings verstehe ich hier nicht was dass x und was das y ist.

ich dachte ich brauche die spalten einzeln, da man sich nachher bei der ausgabe leichter tut, oder irre ich mich da? Denn wenn ich es so sortiere kann ich die daten dann ja nciht ausgeben oder doch?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 27.09.14 13:26 
Du meinst vermutlich den Lambdaausdruck bei deiner Frage nach x,y. Das ist die Kurzform von der Möglichkeit die TH69 in seiner Antwort in ausführlich zeigt. Die sind von der späteren Ausführung her absolut äquivalent. Der LAmbdaausdruck ist halt nur schön kompakt.

An Sort übergibt man eine Methode die man beim sortieren braucht. Und zwar eine Methode die 2 Elemente vergleicht und jeweils zurückgibt welches der beiden Elemente größer bzw. kleiner ist.
x, y sind einfach die von mir namentlich ausgedachten Bezeichnungen für die beiden Elemente also die Parameternamen der Methode. Hinter dem Pfeil (der nennt sich der Lambda Operator und der Gesamtausdruck ist dann ein Lambdaausdruck) folgt dann sozusagen die Methodenimplementierung wobei die Signatur der an Sort übergebenen Methode erzwingt das da ein Int zurückkommt. Die Methodenimplementierung muß also entsprechendes zurückliefern man kann sich aber das Schlüsselwort return das man ja braucht um etwas aus einer Methode zurückzugeben sparen.

Um es mal umgekehrt auszubauen, ohne Lambdaausdruck, sehe das so aus

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
private static int TheSortMethod(Liste x, Liste y)
{
  return x.Alter.CompareTo(y.Alter);
}
 
list.Sort(TheSortMethod);


Das ist aber nicht wirklich kompakt. Man braucht die Methode ja auch höchstwahrscheinlich nur genau an dieser Stelle. Also wäre ein Schritt daraus erstmal eine anonyme Methode zu machen so das ich die Methodenimplementierungen da gleich hinschreiben kann ohne eine Methode explizit zu definieren. Also

ausblenden C#-Quelltext
1:
list.Sort(delegate(Liste x, Liste y) { return x.Alter.CompareTo(y.Alter); });					


Jetzt stellt man fest das man ja eigentlich weiß das in der Liste Objekte vom Typ Liste sind. Auch der Compiler sollte sich dem einfach bewußt sein. Also kann man auch gleich die geschwätzige Definition der Methodensignatur weglassen. Genauso weiß man ja auch das die Methode etwas zurückliefern muß also kann man sich auch gleich das Wörtchen return sparen. Dann ist man bei der kompakten Form die man dem Syntax her dem Lambda-Kalkül angepasst hat. Eben

ausblenden C#-Quelltext
1:
list.Sort((x,y) => x.Alter.CompareTo(y.Alter));					



Zitat:
ich dachte ich brauche die spalten einzeln, da man sich nachher bei der ausgabe leichter tut, oder irre ich mich da? Denn wenn ich es so sortiere kann ich die daten dann ja nciht ausgeben oder doch?


Ja, du irrst dich. Was hat die Sortierung der Daten mit der Ausgabe der Daten zu tun? Im Moment würde ich dir raten es einfach mal zu probieren und dann wenn es nicht klappt uns denn Code zu zeigen.

Für diesen Beitrag haben gedankt: Adabei
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Sa 27.09.14 14:43 
ok, habe jetzt mals versucht, bekomme aber dann als ausgabe kein alter sondern immer nur Projekt.Liste als ausgabe.
Projekt nenne ich das ganze Projekt, also das ganze Programm und Liste ist ja die eine Liste die ich erstellt habe
welchen code im speziellen brauch ihr noch?, oben habe ich ja schon fast den ganzen reingetan, hier aber noch die ausgaben

ausblenden C#-Quelltext
1:
2:
3:
m_tb1.Text += myList[0];
                m_tb2.Text += myList[1];
                m_tb3.Text += myList[2];;

sortiert habe ich es so wie ihr es mir erklärt habt.


Noch eine kurze Zwischenfrage:

Ich will dass wenn eine textbox leer ist(m_tbname), der Benutzter nicht auf einen Button klicken kann(m_btnstarten), wenn allerdings irgendetwas in dieser texbox drinnen steht sollte er den button klicken können, welchen fehler habe ich bei diesem code gemacht?

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (String.IsNullOrEmpty(m_tbname.Text))
                {
                    m_btnstarten.Enabled = false;
                    if (!string.IsNullOrEmpty(m_tbname.Text))
                    {
                        m_btnstarten.Enabled = true;
                    }
                }


lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 27.09.14 15:18 
In myList[0] steckt ja auch genau so ein Objekt der Klasse Liste drin. Wenn du das Alter anzeigen willst solltest du auch das Alter zuweisen. Also

ausblenden C#-Quelltext
1:
m_tb1.Text += myList[0].Alter;					



Bei deinem Code ist falsch die beiden ifs zu schachteln. Der 2.te if kann nie zu true ausgewertet werden weil du da ja nur hinkommst wenn genau das gegenteil gilt was du ja im 1.ten if ausgewertet hast. Du müßtest du beiden if abfragen also nacheinander ausführen.

Du kannst das ganze aber auch ohne ifs darstellen. Du wertest mit dem if einen Ausdruck der entweder true oder false sein kann um dann einen Wert zuzuweisen der tre oder false sein kann. Das kannst du dann natürlich auch direkt machen.

ausblenden C#-Quelltext
1:
m_btnstarten.Enabled = !String.IsNullOrEmpty(m_tbname.Text);					

Für diesen Beitrag haben gedankt: Adabei
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Sa 27.09.14 15:39 
ok, jetzt zeigt es zumindest schon mal irgendetwas an, aber leider nicht das alter absteigend, also muss bei meiner liste sortieren auch irgendetwas falsch sein, aber was?
ausblenden C#-Quelltext
1:
myList.Sort((x, y) => x.Alter.CompareTo(y.Alter));					

habe ich ja genau so gemacht wie du es mir erklärt hast, nur funktioniert es leider nicht

geht dass nicht so auch?
ausblenden C#-Quelltext
1:
2:
myList.Sort();
                myList.Reverse();


nochmals zum andern:
ja habe jetzt mal die beiden ifs nacheiandern gemacht, am anfang ist der button disabled, weil ja nichts drinnen steht, aber wenn ich nun in die textbox was reinschreibe, dann bleibt er leider disabled, es ist egal was ich reinschreibe er bleibt immer grau hinterlegt(wie er nur sein soll wennn nichts in der textbox drinnensteht)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 28.09.14 21:50 
user profile iconAdabei hat folgendes geschrieben Zum zitierten Posting springen:
ok, jetzt zeigt es zumindest schon mal irgendetwas an, aber leider nicht das alter absteigend, also muss bei meiner liste sortieren auch irgendetwas falsch sein, aber was?
ausblenden C#-Quelltext
1:
myList.Sort((x, y) => x.Alter.CompareTo(y.Alter));					

habe ich ja genau so gemacht wie du es mir erklärt hast, nur funktioniert es leider nicht

Das wird dir die jüngste Person nach vorne spülen. Wenn es in deiner UI nicht als erstes ankommt machst du drum herum irgendwas falsch.
Zitat:
geht dass nicht so auch?
ausblenden C#-Quelltext
1:
2:
myList.Sort();
                myList.Reverse();

Für ein Sort ohne Übergabe eine Sort Methode müßte die Klasse Liste IComparable implementieren. Das macht aber nur Sinn für Klassen die genau eine sinnvolle Sortierungen hätten. Bei deiner fällt mir zumindest die Sortierung nach Name oder Alter ein. Reverse dreht die Sortierung nur. Wo ist da der Sinn wenn mann doch gleich einfach richtig sortieren kann?
Zitat:
nochmals zum andern:
ja habe jetzt mal die beiden ifs nacheiandern gemacht, am anfang ist der button disabled, weil ja nichts drinnen steht, aber wenn ich nun in die textbox was reinschreibe, dann bleibt er leider disabled, es ist egal was ich reinschreibe er bleibt immer grau hinterlegt(wie er nur sein soll wennn nichts in der textbox drinnensteht
)
Ohne Code was du machst und inbesondere wo du es machst kann man da nix zu sagen.

Wie sieht es mit deinen Debugging Fähigkeiten aus? Gerade das letzte Problem sollte leicht zu lösen sein wenn man einfaches debuggen beherrscht und anwendet(und fragen beantwortet wie etwa "wird mein Code überhaupt aufgerufen", "was macht der wenn er aufgerufen wird", wenn er nicht tut was ich erwarte "was muss ich ändern").

Für diesen Beitrag haben gedankt: Adabei
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Mo 29.09.14 18:11 
ja die jüngsten personen werden zuerst angezeigt, aber es sollte ja umgekehrt sein, dass zuerst die älteren kommen...

leider habe ich da noch überhaupt keine erfahrung mit debugging, habe es zwar schon mal gehört, aber mehr nicht, da ich ja noch ein anfänger bin.

also ich habe den Code in die set methode der klasse reinprogrammiert.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
public List<Liste> Liste
        {
            get
            {
                return myList;
            }
            set
            {
                myList = value;
                if (String.IsNullOrEmpty(m_tbname.Text))
                {
                    m_btnstarten.Enabled = false;
                }
                if (!string.IsNullOrEmpty(m_tbname.Text))
                {
                    m_btnstarten.Enabled = true;
                }
                
            }


woanders kann man es ja nicht reinprogrammieren außer im set-teil oder etwa doch?, denn einen eigenen button mit eingabe überprüfen will ich nicht machen, da dann das UI extrem schlecht aussieht;
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 29.09.14 18:19 
Zitat:
ja die jüngsten personen werden zuerst angezeigt, aber es sollte ja umgekehrt sein, dass zuerst die älteren kommen...


Ok. Dann tausche doch einfach in der Sort Methode x und y. Aber ein reverse tuts auch.

Zitat:
woanders kann man es ja nicht reinprogrammieren außer im set-teil oder etwa doch?


Wenn ich dich verstanden habe möchtest du das sich der Button zustand ändert wenn etwas in die TextBoxen geschrieben wird. Heißt du mußt auch dafür sorgen das wen nsich der Text ändert der Code auch aufgerufen wurde. Der Propertysetter wird da sicherlich nicht automagisch aufgerufen.

TextBoxen haben einen TextChanged Event dort solltest du denn entsprechenden Test vornehmen und deine Buttons enablen/disablen.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 29.09.14 18:41 
Und für den Debugger lies dir mal Debugger: Wie verwende ich den von Visual Studio? durch und wende diese an (Haltepunkte, überwachte Ausdrücke, Einzelschritt, etc.).
Adabei Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Mo 29.09.14 19:21 
ok, danke für alles, es funktioniert nun.

ich habe den button zuerst auf set mal disabled und dann bei der textbox doppelklick gemacht und dort die ifs reingetan und jetzt funktionierts einwadnfrei,

beim sortieren habe ich eifnach x und y vertauscht und nun läufts wie gewünscht

danke!!!

ps.: werde ich in den nächsten tagen mal durchlesen und dann auch ausprobieren