DatagridView grafic Cells mitZahl überlagern

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    Du hast die Basisklasse Object angewählt. Wähl mal System.Drawing.Rectangle an.

    Beschäftige dich auch nochmal mit VisualStudio richtig nutzen (Google ist nicht deine Mami) , bes. den letzten Post, wie man den OB günstigerweise einstellt.
    Aber auch das Video gucken, wie man ihn dann effizient nutzt.

    ErfinderDesRades schrieb:

    Du hast die Basisklasse Object angewählt. Wähl mal System.Drawing.Rectangle an.


    Das habe ich schon vorher getan (s. Anhang). Aber auch da finde ich nix.

    Jetzt lass uns doch nicht um den heißen Brei herum reden. Ich gestehe freimütig meine umfassende Inkompetenz ein ... aber jetzt sag mir doch endlich, wo ich was finde ! Auch ohne Tut "Google is not your mother" ... :)

    LG
    Peter
    Bilder
    • s 2017-12-18 12-50-422.jpg

      209,29 kB, 987×694, 51 mal angesehen
    Also, ich will gern was lernen. Auch die Bedienung des ObjectBrowsers. Dazu bin ich ja hier. Ich hab mir auch sehr viel Mühe gegeben, deine Ratschläge umzusetzen. Aber ich bin halt kein Hellseher.

    Rectangle.Inflate kann die Größe eines Rechtecks verändern. Aber jetzt mal ganz im Ernst, das hab ich doch mit der folgenden Technik auch hin bekommen:

    VB.NET-Quellcode

    1. Dim myCircle As Rectangle = myCellBounds 'Define size of circle
    2. myCircle.X += 5
    3. myCircle.Y += 5
    4. myCircle.Height -= 10
    5. myCircle.Width -= 10


    Ich hab doch geschrieben, dass die Sache mit der Größe des Kreises längst erledigt ist. Insofern verstehe ich deinen Punkt jetzt nicht.

    Mein Problem ist es, wie ich die Zellen der DatagridView neu malen kann, ohne dass ich im CellPainting Event bin. Denn wenn ich eine Zelle durch Click besetze, dann ändert sich nicht nur diese Zelle, sondern auch die Zähler anderer Zellen, bzw. der Status anderer Zellen, weil im Reversi ja Steine "umgedreht" werden.

    Also, nochmal: meine zentrale Frage ist, wie ich ich Zellen neu malen kann, AUSSERHALB des CellPainting Events.

    Ich kann dieses Problem umgehen, indem ich einfach die Datagrid View bei jeder Änderung komplett neu aufbaue. Bei 8 x 8 Zellen ist das ja nicht unbedingt ein Thema. Aber ich würde das halt gern "vernünftig" lösen.

    LG
    Peter
    Natürlich hab ich da nix gegen das CellPainting einzuwenden. Dann versuche ich meine Frage einmal anders zu stellen:

    Wenn ich in meiner DatagridView zum Beispiel die Zelle(2, 3) anklicke, dann ändert sich dadurch ihr Inhalt. Das geschieht in CellPainting.

    Gleichzeitig muss jetzt aber auch möglicherweise etwa die Zelle(3, 4) geändert werden, weil sich ihr Zähler geändert hat und vielleicht auch die Zelle (3, 3) weil sich ihre Farbe geändert hat. Da passiert aber nix ... weil diese Zellen nicht angeklickt wurden.

    Wie stoße ich also nach dem Click auf Zelle(3, 4) das CellPainting an auch für die Zellen(3, 4) und (3, 3) ?

    Ich hoffe, dass es mir gelungen ist, mich jetzt verständlicher auszudrücken.
    Da habe ich mich falsch ausgedrückt. Wenn ich eine Zelle anklicke, verändert sich die ANZEIGE ... und damit muss sich auch die Anzeige in einer anderen Zelle ändern. In beiden Fällen wird gemalt.

    Die Frage ist: wenn CellPaint die Anzeige in einer Zelle ändert, wie kann ich dann das CellPaint Ereignis für eine andere Zelle aufrufen ?

    Das ist doch eigentlich eine klare Fragestellung Ich verstehe wirklich nicht, was daran jetzt so missverständlich sein soll.

    Peter329 schrieb:

    Die Frage ist: wenn CellPaint die Anzeige in einem Feld ändert
    Das Cellpaint ändert keine Anzeige in eim Feld. Es zeigt das Feld nur an. Wenn das Feld geändert ist, kommt eine geänderte Anzeige zur Ansicht.
    So isses jdfs, wenns richtig ist.



    noch einmal: imo brauchst du ein Datenmodell.
    Wenn du ein Feld anklickst, muss sich etwas im Datenmodell ändern. Das kann eine, keine oder viele Zellen betreffen.
    Und die Datenmodell-Änderungen müssen auf die Anzeige rückwirken.
    Lass uns keine Wortklauberei betreiben.

    Also gut, dann machen wir halt mal ein Datenmodell:

    Es gibt eine 8 x 8 Matrix. Die Zellen dieser Matrix können drei Zustände haben:

    leer
    schwarz
    weiß

    Wenn der Zustand "schwarz" ist, dann soll ein schwarzer Kreis angezeigt werden.
    Wenn der Zustand "weiß" ist, dann soll ein weißer Kreis angezeigt werden.
    Wenn der Zustand "leer" ist, dann soll eine Zahl angezeigt werden.

    Den Zustand von einigen leeren Zellen kann man durch Anklicken der Zelle ändern.

    Nach jedem Klick ändert sich der Spieler von schwarz auf weiß oder von weiß auf schwarz.
    Die Zahlen sollen in der Farbe des jeweils aktuellen Spielers angezeigt werden.

    Wenn sich der Zustand einer Zelle ändert, dann ändert sich auch der Zustand von anderen Zellen nach bestimmten Regeln.

    Ich demonstriere das anhand eines Beispiels.

    Ausgangstellung (s. 1. Anhang)

    Anklicken der Zelle, welche die Zahl "3" enthält - Folgestellung (s. 2. Anhang)

    Wie man sieht hat sich durch das Anklicken der Zelle mit der Zahl "3" die Anzeige dieses Feldes verändert, ebenso wie die Anzeige einiger weiterer Felder.

    Jetzt sollten die Verhältnisse doch klar liegen. Wie kann man das denn jetzt realisieren ?

    Es sei angemerkt, dass meine Anwendung völlig fehlerfrei funktioniert, bis auf das Anzeigen der Zahlen !
    Bilder
    • s 2017-12-18 19-59-230.jpg

      28,55 kB, 491×491, 37 mal angesehen
    • s 2017-12-18 19-59-311.jpg

      29,64 kB, 491×491, 48 mal angesehen

    Peter329 schrieb:

    ...Wortklauberei...

    Also gut, dann machen wir halt mal ein Datenmodell:
    Ähm - Ein Datenmodell ist mindestens eine Klasse, meist mehrere - die muss man coden.

    Peter329 schrieb:

    Es gibt eine 8 x 8 Matrix. Die Zellen dieser Matrix können drei Zustände haben:

    leer
    schwarz
    weiß

    Wenn der Zustand "schwarz" ist, dann soll ein schwarzer Kreis angezeigt werden.
    Wenn der Zustand "weiß" ist, dann soll ein weißer Kreis angezeigt werden.
    Wenn der Zustand "leer" ist, dann soll eine Zahl angezeigt werden.

    Den Zustand von einigen leeren Zellen kann man durch Anklicken der Zelle ändern.

    Nach jedem Klick ändert sich der Spieler von schwarz auf weiß oder von weiß auf schwarz.
    Die Zahlen sollen in der Farbe des jeweils aktuellen Spielers angezeigt werden.

    Wenn sich der Zustand einer Zelle ändert, dann ändert sich auch der Zustand von anderen Zellen nach bestimmten Regeln.
    Das ist schon ein recht gutes Pflichtenheft. Klebt allerdings noch viel zu sehr am sichtbaren. Im Datenmodell sollte es nur um Zustände gehen.
    vlt so:
    Es gibt eine 8 x 8 Matrix. Die Zellen dieser Matrix werden durch die beiden Spieler belegt, haben also 3 Zustände:
    • leer
    • Spieler1
    • Spieler2
    Ein Spielzug ist, wenn ein Spieler eine leere Zelle belegt.
    Dadurch ändert sich auch die Belegung anderer Zellen
    (SpielEnde + Gewinner definieren)

    Mehr nicht. Nichts mit Farben, nichts mit Klicken

    So, nun fahre fort mit Post#3
    Also im Design hätte ich jetzt eigentlich keine Hilfe gebraucht. So sieht meine Klasse aus:

    Quellcode

    1. Dim Board(7, 7) as String 'Status
    2. Dim BoardCount(7, 7) as Integer 'Reverse count
    3. ResetBoard() 'Build initial Board
    4. SetNextPlayer() 'Set or switch player
    5. BuildBoardCount() 'Build count table
    6. PerformMove(i, j) 'aufgerufen von Cell MouseClick
    7. UndoRedoMove(direction) 'aufgerufen von ButtonClick Undo / Redo
    8. RebuildDisplay() 'Update DataGridView


    Ich habe jetzt alles was die DatagridView betrifft aus den Methoden herausgenommen. Allein das CellPaint Event verändert jetzt das Aussehen der DatagridView.

    Die Methoden SetupBoard, PerformMove und UndoRedoMove rufen am Ende RebuildDisplay auf. In dieser Methode werden alle Zeilen der DatagridView gelöscht und dann neu eingefügt. Damit werden alle Zellen durch das CellPaint Event neu gemalt.

    Damit funktioniert dann die Sache.

    Für ideal halte ich diese Lösung nicht. Denn ersten malt der Click auf eine Zelle der DatagridView diese Zelle unmitelbar neu (das könnte ich mit einem Flag verhindern) und zweitens verändert ein Zug nur das Aussehen von EINIGEN Zellen. Es werden aber jedesmal ALLE Zellen neu gemalt. Bei einer 8 x 8 Matrix ist das aber kein Performance Problem.

    Ich hätte mir eine Lösung gewünscht, die tatsächlich nur die Zellen neu malt, deren Aussehen sich auch verändert hat. Aber jetzt bleibt das so. Man kann eben nicht alles haben. Und es ist ja auch ganz offensichtlich nicht gar so einfach, mein Anliegen hier verständlich zu machen. Obwohl ich mir schon einbilde, das recht vernünftig dargestellt zu haben. :)

    Herzlichen Dank an meine unermüdlichen Ratgeber und einen schönen Tag.

    LG
    Peter

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Peter329“ ()

    das sind jetzt ein paar Felder und Methoden, aber ein Datenmodell würde besteht ja aus mindestens einer Klasse.

    na egal.

    Beim Dgv kann man ganz einfach das Neuzeichnen einer bestimmten Zelle anstossen: Weise der Value-Property irgendeinen Wert zu, dann zeichnet die Zelle sich neu.
    Oder noch einfacher - guck ma im OB nach Datagridview-Methoden mit I - tja pech, den OB hälste ja für Hexenwerk und Brei-Rederei, nur um dich zu zwingen, Inkompetenz einzugestehen - weisst ja: ich bin ein arrogantes Arsch, und habe immer grosse Freude daran.
    Zu was annerem ist der OB echt nicht nutze.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ok ... InvalidateCell(ixcol, ixrow) ... Da hätte man auch wesentlich weniger Wirbel drum machen können.

    Ich halte den OB keineswegs für Hexenwerk. Nur wenn ich unter "Rectancle" nach Methoden suchen soll, die mit "I" anfangen, dann kann ich nicht fündig werden, weil es die schlicht und ergreifend nicht gibt.

    Aber jetzt bleibt die Sache so wie se iss ! :)

    Ich lasse nämlich nun die Maschine gegen sich selbst spielen, um heraus zu finden, welche Strategien am wirkungsvollsten sind, hehehe ... das macht dann deutlich mehr Spaß !

    LG
    Peter

    Peter329 schrieb:

    Ok ... InvalidateCell(ixcol, ixrow) ... Da hätte man auch wesentlich weniger Wirbel drum machen können.
    Noch mehr Wirbel wäre vermeiden, wenn man mal auf die Idee verfiele, mittm OB selbst nach Antworten auf Fragen zu suchen.
    Anfangs hielt ich dich für einen, der interessiert war, Programmieren zu lernen.
    Du scheinst dich aber zu jmd zu entwickeln, der lieber Lösungen vorgesagt bekommt, als selbst die Mittel zu benutzen, mit denen man sich sachkundig machen kann.



    Peter329 schrieb:

    Nur wenn ich unter "Rectancle" nach Methoden suchen soll, die mit "I" anfangen, dann kann ich nicht fündig werden, weil es die schlicht und ergreifend nicht gibt.



    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Du scheinst dich aber zu jmd zu entwickeln, der lieber Lösungen vorgesagt bekommt, als selbst die Mittel zu benutzen, mit denen man sich sachkundig machen kann.


    Du hast sehr viel Wissen und du gibst mir freundlicherweise sehr gute (wenn auch manchmal etwas kryptische) Ratschläge. Und deswegen lasse ich das jetzt einfach mal so stehen.

    Du hast natürlich recht, es gibt in Rectangle Methoden, die mit "I" anfangen. Nur leider ist keine davon problemrelevant. Also, lass uns hier keine Wortklauberei betreiben.

    Lassen wir es gut sein. Ganz aufrichtig vielen Dank für deine Ratschläge, die ich sehr schätze.

    LG
    Peter