Probleme mit Listbox und Textfarbe

Schönen guten Tag.

Ich habe erst vor kurzem begonnen mich mit Xojo zu beschäftigen und bitte somit um Verständis.
Ausgangssituation:

Ich habe zur Übung mit einer Schulden/Guthaben Liste angefangen wo man einen Namen, Betrag eingeben kann und mit dem AddButton zu der Listbox hinzufügen kann. Das ganze funktioniert soweit schon.

Ich will erreichen das sich die Farbe von jedem Betrag in der Listbox anpasst, je nachdem ob der Betrag positiv oder negativ ist.(positiv= grün) (negativ=rot)
Ich habe eine Funktion integriert die den Namen im Textfeld mit dem Namen in der Listbox vergleicht und wenn dieser schon vorhanden ist soll der Name nicht ein zweites mal angelegt werden sondern der neu eingegebene Betrag einfach zu dem bei dem vorhanden Namen addiert/subtrahiert werden.(Abhängig von den Ration Buttons).

Jetzt mein Problem:

Wenn ich nur neue Namen und Beträge hinzufüge wird die Farbe richtig angezeigt aber sobald ich bei einem vorhanden Namen vom positiven ins negative wechsel verfärben sich gleich alle Zeilen in der Listbox Rot oder Grün.

Ich versteh echt nicht woran das liegen könnte.

Add Button:

If CheckFilledOut = True And NameExist = False Then Listbox_MoneyList.AddRow (txt_Freund.text,txt_Betrag.text) Elseif CheckFilledOut = True And NameExist = True Then Dim BetragFreundVorhanden As Integer = CDbl(Listbox_MoneyList.Cell(WhereNameExist, 1)) Dim BetragAlsZahl As Integer = CDbl(txt_Betrag.Text) Dim BetragAlsString As String BetragFreundVorhanden = BetragFreundVorhanden +BetragAlsZahl BetragAlsString = str(BetragFreundVorhanden) Listbox_MoneyList.Cell(WhereNameExist, 1)= BetragAlsString End If

Listbox CellPaint:

[code] for i As Integer= 0 To myWindow.Listbox_MoneyList.ListCount - 1

if  column=1 And CDbl(myWindow.Listbox_MoneyList.Cell(i, 1))  > 0  then
  g.ForeColor = &c00FF0000
Elseif column =1 And CDbl(myWindow.Listbox_MoneyList.Cell(i, 1)) < 0 then
  g.ForeColor = &cFF000000
end If

next
[/code]

Methoden:

CheckFilledOut

[code] Dim Freund As String = txt_Freund.text
Dim RadioSet As Boolean = False
Dim AmountSet As Boolean = False
Dim NameSet As Boolean = False
Dim Betrag As Integer = CDbl(txt_Betrag.text)

// Überprüfung RadioButton gesetzt
if RadioButton_Guthaben.Value = False And RadioButton_Schulden.Value = False then
MsgBox “Es wurde nicht ausgewählt ob Schulden oder Guthaben verbucht werden soll.”
else
RadioSet = True
end if
// Überprüfung ob Betrag angegeben
if Betrag = 0 Then
MsgBox “Kein Betrag angegeben.”
else
AmountSet = True
end if

// Überprüfung Name ob angegeben
if Freund = “” Then
MsgBox “Kein Name angegeben”
else
NameSet = True
end if

// Überprüfung ob Name vorhanden

// Wenn alles zutrifft weiter

if RadioSet and AmountSet and NameSet = True Then
Return True
end If[/code]

NameExists

  // LOOP THROUGH THE Listbox
  for i As Integer=  myWindow.Listbox_MoneyList.ListCount - 1 DownTo 0
    
    // IF NEW NAME ALREADY EXISTS
    if   myWindow.Listbox_MoneyList.Cell(i, 0) = txt_Freund.text then
      // DISPLAY THE ERROR MSGBOX
      Return True
      Exit For i
    end if
  next

WhereNameExists

[code] // LOOP THROUGH THE Listbox
for i As Integer= myWindow.Listbox_MoneyList.ListCount - 1 DownTo 0
if myWindow.Listbox_MoneyList.Cell(i, 0) = txt_Freund.text then

  Return i
  Exit For i
  
end if

next
[/code]

Vielleicht hat von euch jemand eine Idee. Danke schon mal im voraus.

Ohne das alles in Vollstndigkeit angeschaut zu haben: Nimm im Event einmal die Schleife heraus. Der CellTextPaint-Event wird fr jede Zelle aufgerufen, die aktualisiert wird du musst also nicht alles in der Schleife durchgehen, sondern kannst einfach die gelieferten Werte fr Row & Column verwenden, um die aktuelle Zelle zu bestimmen, ggf. mit Cell(Row, Column) darauf zugreifen und die Textfarbe setzen.

Der Fehler liegt im CellTextPaint event. Für JEDE Zelle rennst du über die GESAMTE ListBox und malst die column 1 erneut (also alles in column 1 rot, dann alles grün, dann alles rot etc), dadurch bleibt am Ende nur übrig was du zuletzt gemalt hast.

Der Code sollte sein

[code]if column = 1 then

if CDbl(me.Cell( row, 1)) < 0  then
    g.ForeColor = &cFF000000
Else
    g.ForeColor = &c00FF0000
end If

end if[/code]

P.S. Du must dir das so vorstellen:

was im CellTextPaint event steht führt JEDE sichtbare Zelle selbstständig aus, und zwar jedesmal wenn die Zelle neu gemalt wird (also etwa 60 mal pro Sekunde).

Wenn also einfach drinsteht

g.ForeColor = &cFF000000

dann malt sich jede Zelle in der Farbe rot an.

Das kann man einschränken auf bestimmte Kolumnen, Reihen, oder Zellen. Dazu verwendet man die Parameter column und row die in der Definition der Methode stehen:

Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean

Also um es auf Kolumne 1 zu beschränken: if column = 1 then g.ForeColor = &cFF000000

Um es auf Reihe 3 zu beschränken: if row = 3 then g.ForeColor = &cFF000000

Um es auf Zelle (2,5) zu beschränken: if column = 2 and row = 5 then g.ForeColor = &cFF000000

Außerdem möchte ich auf self und me hinweisen: innerhalb einer Control ist me die Control die benutzt wird (zB Listbox, PushButton) und self ist idR das Fenster auf dem man ist.

Also kannst du statt myWindow.Listbox_MoneyList.ListCount - 1 einfach me.ListCount - 1 sagen.

Vielen herzlichen Dank für eure Hilfe. Hat mir fürs Verständnis wirklich geholfen.

Bezüglich:

Wäre dann self.me.ListCount -1 auch richtig bzw. wieso kann ich das mywindow einfach weglassen ?

Eine Frage hätte ich noch. Wie würdet ihr zB.: -100 zu +100 machen.
Ich habe in die RadioButtons für Schulden also - folgendes geschrieben::

If cdbl(txt_Betrag.text) > 0 Then txt_Betrag.text = "-" + txt_Betrag.text End If

Aber wie bekomme ich das “-” wieder weg wenn ich auf den Radio Button für Guthaben klick ?

Danke euch :slight_smile:

Das self ist hier nicht nötig da die Listbox auf dem Fenster ja weiß auf welchem Fenster sie ist (intern hat sie ihren parent gespeichert), und die Listbox sprichst du ja innerhalb der Listbox einfach mit me an.

[quote]Eine Frage hätte ich noch. Wie würdet ihr zB.: -100 zu +100 machen.
Ich habe in die RadioButtons für Schulden also - folgendes geschrieben::

If cdbl(txt_Betrag.text) > 0 Then txt_Betrag.text = "-" + txt_Betrag.text End If

Du kannst zB innerhalb der Listbox schreiben self.top = 50 und dann bewegt sich daß Fenster (=self) so daß die obere Kante bei 50 liegt.

Du fügst mit deinem Code immer nur ein “-” vorne dran, aber du beeinflusst den WERT nicht.

“1” ist nicht das selbe wie 1.

“1” ist TEXT

1 ist eine ZAHL, ein WERT

In einem TEXTfeld steht immer TEXT, rechnen mußt du aber mit ZAHLEN. Daher auch vorher umwandeln!

Einfach mit (TF_1 ist das TextFeld):

TF_1.text = Str( - CDbl( TF_1.text ) )

Du wandelst den WERT ins negative (wobei was negatives positiv wird) und wandelst den neuen Wert dann in Text um

Also von innen nach außen:

TF_1.text = Str( - CDbl( TF_1.text ) ) // nimm den Text, zB: “-5”
TF_1.text = Str( - [b]CDbl/b ) // wandel ihn um in eine Zahl: -5
TF_1.text = Str( - CDbl( TF_1.text ) ) // wandel die Zahl ins negative: 5
TF_1.text = Str( - CDbl( TF_1.text ) ) // wandel die Zahl in Text: “5”
TF_1.text = Str( - CDbl( TF_1.text ) ) // stopf den Text ins Textfeld

P.S. Sepp & Ulrich, fügt doch in eurem Profil mal dazu wo ihr seid :wink:

Dankeschön für die schnelle und kompetente Hilfe =)
So einfach kann es manchmal gehen. Ich hab eher an String-Formatierung gedacht.

[quote=165529:@Sepp Gruber]Dankeschön für die schnelle und kompetente Hilfe =)
So einfach kann es manchmal gehen. Ich hab eher an String-Formatierung gedacht.[/quote]
Mit Strings rechnet es sich halt schlecht:

1 + 1 = 2

“1” + “1” = “11”

  • ( -5 ) = 5

“-” “-5” = “–5”

:wink:

Aber glaub mir, wir sind ALLE mal drauf reingefallen :stuck_out_tongue_winking_eye:

Sepp, den Thread bitte noch als beantwortet markieren :wink: