Transparentes UserControl auf einem DataGridView...

louk

Grünschnabel
Hallo,

hab ein UserControl, dass bei Falscheingabe in einer DataGridView aufgeschaltet wird. Das UserControl ist transparent und bettet 2 Images, einen Text und ein gelbes Rechteck mit schwarzem Rand ein. Sind zu wenig Zeilen im Grid, wird das UserControl am Rand der DGV gezeichnet und kann dann über einem Scrollbalken liegen. Das UC ist der ControlCollection der TabPage hinzugefügt worden, in dem auch die DGV liegt.
Mein Problem ist, dass sich die Scrollbar über das UC legt (auch beim Hoovern mit der Mouse). Wie bekomme ich das UC zu oberst geschaltet? BringToFront() hat leider nicht geholfen und TopMost gibt es nicht. Ein Problem ist auch der ButtomUpClick auf eine Zelle, nachdem das UC ausgelöst vom DownClick gezeichnet wurde. Dann zeichnet sich die Zelle auch nach vorne (Siehe Bildanhang).

Bin mir nicht mehr Sicher, ob das mit einem UC überhaupt zu lösen ist. Wäre für Hilfe sehr dankbar.
 

Anhänge

  • InfoBoxFehler2.PNG
    InfoBoxFehler2.PNG
    6,1 KB · Aufrufe: 196
Nach Disablen der Transparenzeinstellung in CreatePrams, zeichnet sich die Scrollbar nicht mehr durch, dafür wird aber der Hintergrund beim Wechsel von einer anderen Form übernommen statt dem von der DGV.

Code:
protected override CreateParams CreateParams
{
	get{
		CreateParams cp = base.CreateParams;
		//cp.ExStyle |= 0x20;
		return cp;
	}
}

Es wird noch eine OnPaintBackground überschrieben, so dass der Hintergrund transparent (nicht überschrieben) erscheint.

Code:
protected override void OnPaintBackground(PaintEventArgs e)
{
	//base.OnPaintBackground(e);		
}

Die Property BackColor des UserControls ist auf Transparent gesetzt.

Das Problem haben mit Sicherheit andere auch schon gehabt. Kennt jemand eine Lösung?
 

Anhänge

  • InfoBoxFehler3.PNG
    InfoBoxFehler3.PNG
    9,7 KB · Aufrufe: 113
Da passiert folgendes. Das DGV sagt sich, in dem Rechteck wo das UC liegt, da darf ich nicht reinzeichnen weil es über mir liegt und das UC ist so programmiert, dass es seinen Hintergrund nicht zeichnet, damit es transparent bleibt. Wenn jetzt eine andere Form drüber liegt, wird der Bildschirm überzeichnet. Wird meine Form wieder nach vorne geholt, lässt das DGV das Areal wo das UC liegt unberührt und das UC zeichnet in seinen Hintergrund nichts rein und schon haben wir den Salat. Beim ersten Aufschalten des UC passt der Hintergrund noch. Deswegen merkt man noch nichts. Zur Lösung habe ich jetzt folgendes in das UC eingebaut. Ich hänge mich in das Activated Event der Form rein, heide das UC, refreshe den Parent vom DGV und showe das UC wieder und siehe da, Problem gelöst.

Beim ersten Anzeigen des UC hänge ich den Event ein:

Code:
(m_dgv.TopLevelControl as Form).Activated += new EventHandler(Form_Activated);

private void Form_Activated(object sender, EventArgs e)
{
	Hide();		   // UC verstecken
	m_dgv.Parent.Refresh(); // Refresh der unterliegenden TabPage, in dem das DGV liegt
	Show();		   // UC anzeigen
}


Diese Refresh Miemik (Hide, Refresh, Show) benutze ich auch noch beim Resize bzw. verschieben des UC.
Man liest hier und da von Problemen der Programmierer, dass es zur Schlierenbildung beim Verschieben des UC kommt. Die hatte ich auch, was sich aber mit dem Gimik abstellen lässt.
Man muss einfach im Hinterkopf behalten, dass man sich bei einem UC, dass seinen Hintergrund nicht zeichnet, selbst um den Hintergrund kümmern muss wenn es nötig ist, da es sich hier nicht um eine echte Transparenz von übereinander liegenden Objekten handelt sondern lediglich der Hintergrund unberührt bleibt. Hat man in dem UC Areal aber selber schon rumgezeichnet und zeichnet an benachbarter Stelle weiter, werden die schon gezeichneten Flächen nicht restauriert. Das darf man selber erledigen (z.B. durch UC verstecken, unterliegende Fläche neu zeichnen (bzw. Controls damit beauftragen) und UC wieder an neuer Position anzeigen).

Damit der Pfeilhintergrund transparent erscheint, wird er im Paint Event des UC per DrawImage ausgegeben. Als eigenständiges Control innerhalb des UC würde die PictureBox ihren Hintergrund sonst selbst zeichnen und dann den Hintergrund überzeichnen.


Im Konstruktor: wird lediglich SetStyle(ControlStyles.Opaque, true) verwendet, CreateParams und OnPaintBackground müssen nicht überschrieben
werden. Das UC ist der ControlCollection der TabPage hinzugefügt. Die Pfeil PictureBox wird gehidet.

Und im Paint-Event wird aus dem PicturBox Control nur das Image und die Position zur Ausgabe genutzt.


Code:
			// Pfeil transparent zeichnen
e.Graphics.DrawImage(pb_Arrow.Image, pb_Arrow.Location.X, pb_Arrow.Location.Y);


Mit BringToFront() wird das UC nach oben geholt. Der Rest ist standard Programmierung.

Wer Transparente UCs verwendet, stößt sofort auf die obigen Probleme. Das sich in diesem Forum keiner gefunden hat, der eine Antwort wusste, finde ich schwach. Danke für die Aufmerksamkeit und tschüss.;-]
 
Anstatt m_dgv.Parent.Refresh() könnte man auch InvalidateEx() wie unten gezeigt verwenden.

Code:
protected void InvalidateEx()
{
	if (Parent == null)
		return;
	Rectangle rc = new Rectangle(this.Location, this.Size);
	Parent.Invalidate(rc, true);
	Parent.Update();
}

Hab aber eine neues Problem. Wenn der Bildschrimschoner durch z.B. einen Mausbewegung abgestellt wird, ist der Hintergrund des UC schwarz. Wenn der Form Activated event kommt, ist das DGV noch nicht gezeichnet und dann geht es wieder in die Hose. Gleiches gilt, wenn die Form geschrumpft war und dann wieder angezeigt wird. Auch dann passt der Hintergrund nicht, weil von der Form bloss die Titelzeile gezeichnet ist, bevor das UC painted.

Das Problem müssten eigentlich auch jede Menge Programmierer haben, die Transparente UC verwenden. Weiss einer wie man das löst?
 
Zurück