DrawString in PictureBox verschwindet

FwDonnerbalken

Erfahrenes Mitglied
Hallo zusammen,

ich schlage mich gerade mit dem Problem rum, dass ich einen Text mittels DrawString in eine PictureBox schreibe, ich tue dies, da ich den Text auch rotiert darstellen möchte.
Die PictureBox verwende ich, da ich einen Container zum zeichnen brauchte, sie ist beliebig ersetzbar.

Der Reihe nach:
Ich habe ein neues Windows Steuerelement erstellt, in diesem habe ich ein TableLayoutPanel platziert, welches zum einen meine PictureBox und zum anderen ein DataGridView beinhaltet.
Über eine Eigenschaft wird der Text festgelegt, der in die PictureBox gerendert werden soll.
Außerdem habe ich OnPaint überschrieben (Code folgt), wo ich den Text neu render.

Leider ist der Text nicht immer dargestellt, bzw. nur dann, wenn ein Resize kommt. Wenn die PictureBox aus dem Bildschirm und wieder zurück gezogen wird, ist der Text ebenfalls weg.

Ich suche eine Möglichkeit, den Text permanent dazustellen, wie z.B. in einem Label.

Code 1: Rendern des Textes (ist unvollständig, nur das Wichtigste)
C#:
Graphics g = control.CreateGraphics();
g.Clear(control.Parent.BackColor);

//Text ausgeben
g.DrawString(text, font, new SolidBrush(Color.Black), 0, 0);

Code 2: OnPaint
C#:
protected override void OnPaint(PaintEventArgs e)
{
    RenderText(columnHeaderBox, _columnHeaderText, RotationAlignment.Normal);
}
RenderText ist die Methode, in der unter anderem Code 1 ausgeführt wird.
 
Entweder beim festlegen des Textes die Funktion Invalidate der PictureBox aufrufen oder du zeichnest fest in eine Bitmap.

PHP:
using (Graphics g = Graphics.FromImage(meineBitmap))
{
   g.Clear(control.Parent.BackColor);
   g.DrawString(text, font, new SolidBrush(Color.Black), 0, 0); 
   g.Flush(); 
}
so ungefähr.

Wobei ich glaub Invalide bleibt dir trotzdem nicht erspart :rolleyes:
 
Die Lösung, eine Bitmap zu verwenden kommt nicht in Frage.

Bzgl. dem Invalidate: das habe ich mal ausprobiert. Und zwar habe ich die es zu folgenden Zeitpunkten aufgerufen, leider ohne Erfolg:

1. Text-Eigenschaft, vor RenderText()
2. In RenderText() nach DrawString()
3. Nachdem alle RenderText()-Operationen durchgeführt wurden in der OnPaint-Methode

By the way:
Interessanterweise habe ich mal ein kleines Control geschrieben, welches eine Linie und einen Text direkt auf das Control zeichnet, dort habe ich ebenfalls mit Invalidate gearbeitet. Hier gibt es keine Probleme.
Das Zeichnen führe ich dort ebenfalls in der OnPaint-Methode durch.

In meinem ersten Post habe ich nicht erwähnt, dass das Control (PictureBox + DataGridView) in einem SplitContainer liegt. Könnte es ggf. daran liegen?
 
Hast du Invalidate im OnPaint Ereignis ausgelöst :confused:

Die Funktion muss außerhalb aufgerufen werden, du willst dem Control ja sagen das es sich neu zeichnen soll. (z.B.: wenn eine neue Zelle im Grid ausgewählt wird)

Edit: Alternativ einfach mal Invalidate von SplitContainer (oder dem Panel) aufrufen.
 
3. Nachdem alle RenderText()-Operationen durchgeführt wurden in der OnPaint-Methode

Deshalb fragst du, oder? Das war nur ein Versuch, der logischerweise scheitern musste. Ich rufe Invalidate im set der Eigenschaft auf. In der OnPaint Methode wie gesagt nur meine RenderText-Methode, die eben den String zeichnen soll.

Eigentlich sollte das klappen, ich bin deshalb etwas ratlos. Deshalb habe ich in meinem letzten Post noch auf den splitContainer hingewiesen. :confused:
 
Habs gerade gtestet bei mir Funktionierts mit Invalidate auf PictureBox mit SplitCOntainer.

Aber was mit gerade aufgefallen ist
PHP:
Graphics g = control.CreateGraphics();
Warum übergibst du der RenderText Funktion nicht direkt das Graphics Objekt von PaintEventArgs?

Habs dann mal mit CreateGraphics() probiert wie du es machst und dann hatte ich das gleiche Problem wie du.

Also besser Graphics Objekt von PaintEventArgs verwenden.
 
Würde ich Graphics Objekt aus den PaintEventArgs verwenden, dann erhalte ich ja den kompletten Zeichenbereich für das Control.

Das ist ja grundsätzlich auch in Ordnung. Nun stelle ich mir nur die Frage, wie ich Location meiner PictureBox auf dem Control erhalte. Da ich diese ja in einem TableLayoutPanel liegen habe, kann ich nicht die Location-Eigenschaft der PictureBox auslesen, diese liefert mir 0; 0. Aus der Sicht des Controls selbst, könnte das aber 100;200 oder was auch immer sein.

Gibt es eine Möglichkeit die Koordinaten der PictureBox auf die absoluten Koordinaten des Controls (des Graphics-Objekt) umzurechnen?
 
das einzige was mir einfält wäre
PHP:
meinControl.RectangleToScreen(meinControl.Bounds)
und dort dann ev. X und Y vom Fenster abziehen.
Falls du sowas gesucht hast.

Wobei ich immernoch nicht wirklich verstanden hab warum es nicht mit dem anderen Graphics Objekt gehen soll :rolleyes:
 
Nach langer Abstinenz von diesem Thema heute der Rückfall! Habe mich gestern nochmal mit diesen besch.... Graphics-Objekt gekloppt und das blöde Ding behält immer noch nicht seinen gemalten Text.
Interessanterweise musste ich jedoch folgendes festellen: Ich habe mittlerweile einen ToolStrip im Control platziert, sobald man mit Maus über einen der ToolStripButtons fährt (der erhält dann diese Hovermarkierung) wird die OnPaint-Methode aufgerufen und meine Strings gezeichnet. Platziert man wieder ein anderes Fenster etc. über dem Text, dann isser futsch

Sorry, aber langsam bekomm ich das kotzen :mad: (entschuldigt bitte diesen Ausdruck)
 
Wie futsch?
Steht einfach nixs mehr da oder zeigt er ev. noch Teile des anderen Forms an?
Kann mir nur weiterhin vorstellen das Invalidate falsch aufgerufen wird. (und das Graphics Objekt hatte ich ja schon angesprochen ;))
Ohne mehr Quelltext wirds ziemlich schwer den Fehler zu finden.

Spyke (www.iv-interactive.de)
 

Neue Beiträge

Zurück