hi!
im anhang ist ein 32kb bild, das mein problem sofort verdeutlicht.
das sind zwei custom buttons, die ich im Form_Load() so erstelle:
CustomButton button1 = new CustomButton();
button1.Parent = this;
button1.Location = new System.Drawing.Point(100, 90);
button1.Size = new System.Drawing.Size(150, 150);
button1.BringToFront();
CustomButton button2 = new CustomButton();
button2.Parent = this;
button2.Location = new System.Drawing.Point(400, 90);
button2.Size = new System.Drawing.Size(150, 150);
button2.BringToFront();
ist der button auf Form1 ist alles okay, da diese die gleiche hintergrundfarbe hat. ist der button über einer textbox oder jedem anderen weißen steuerelement, habe ich einen unschönen, rechteckigen rand.
hier die kleine klasse dazu:
class CustomButton : Button
{
public CustomButton()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle|= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//has to be empty!!!
}
protected override void OnPaint(PaintEventArgs e)
{
base.InvokePaintBackground(this, e);
Graphics g = e.Graphics;
ButtonRenderer.DrawParentBackground(g, ClientRectangle, this);
g.SmoothingMode = SmoothingMode.HighQuality;
//Funktion zum Zeichnen des abgerundeten Rechtecks aufrufen
using (GraphicsPath outerPath = RoundedRectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height, 20.00F))
{
using (SolidBrush outerBrush = new SolidBrush(Color.Black))
{
g.FillPath(outerBrush, outerPath);
}
}
}
//abgerundetes Rechteck erstellen
private GraphicsPath RoundedRectangle(float x, float y, float width, float height, float radius)
{
GraphicsPath gp = new GraphicsPath();
gp.AddLine(x + radius, y, x + width - (radius * 2), y); // Line
gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90); // Corner
gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2)); // Line
gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90); // Corner
gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height); // Line
gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90); // Corner
gp.AddLine(x, y + height - (radius * 2), x, y + radius); // Line
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner
gp.CloseFigure();
return gp;
}
}
wie ihr seht, habe ich schon versucht einige tipps aus anderen threads zu befolgen, leider wird das rechteckt mit der farbe der Form1 nicht ausgeblendet.
habt ihr eine idee?
danke!!
Hi,
base.InvokePaintBackground(this, e);
Graphics g = e.Graphics;
ButtonRenderer.DrawParentBackground(g, ClientRectangle, this);
g.SmoothingMode = SmoothingMode.HighQuality;
Ich vermute mal stark, dass es schlicht an der falschen Hintergrundfarbe liegt. Schau mal, was bei dem Button als BackColor eingestellt ist.
Gruß
Roland
Hallo Blacal,
ich würde nicht sagen, an der Hintergrundfarbe, sondern überhaupt daran, dass ParentBackground gezeichnet wird.
herbivore
Das ist imho ein Bug (Feature?) in GDI, dass Controls auf der gleichen Ebene nicht als Background behandelt werden. Sprich, Parent von der TextBox und dem Button sind beide Male die Form, also wird auch nur der Background der Form gezeichnet, und nicht die TextBox.
Gruß, Christian.
Hallo TheBrainiac,
Das ist imho ein Bug (Feature?) in GDI, dass Controls auf der gleichen Ebene nicht als Background behandelt werden.
das ist ein Feature. Mit anderen Worten: works as designed. Das Design stammt ja noch aus einer Zeit, als eine andere Entscheidung performance-kritisch gewesen wäre. Mit anderen Worten: Transparenz wird in Windows Forms nach einem vereinfachten Modell berechnet, nämlich so wie du sagst, dass man durch ein Control hindurch nicht die dahinerlegenden Controls sieht, sondern nur den Background des Parents. Anderseits könnte man natürlich die TextBox als Parent wählen, dann würde man sie bzw. ihren Background auch sehen.
herbivore
hi!
die hintergrundfarbe habe ich bereits auf transparent gesetzt:
public CustomButton()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
}
es ist richtig, dass die hintergrundfarbe der hintergrundfarbe des parent-steuerelementes entspricht. bei einer textbox mag das noch gehen (so lange kein text drin steht, dann würde sich das rechteck wieder abzeichnen), aber bei einem datagridview mit den gridlines dazwischen, sieht man das rechteck dann wiederum sehr deutlich, da es die gridlines überdeckt.
es muss doch eine möglichkeit geben, dieses hintergrund-rechteck auszublenden oder wirklich transparent zu machen!? 8o
btw: wenn ich "ButtonRenderer.DrawParentBackground(g, ClientRectangle, this);" rausnehme, ist das rechteck dahinter einfach schwarz, aber immer noch existent.
grüße!
Hallo uNki,
es muss doch eine möglichkeit geben, dieses hintergrund-rechteck auszublenden oder wirklich transparent zu machen!?
wie schon gesagt, funktioniert Transparenz unter Windows Forms nach einem vereinfachten Modell. Wenn man nicht gerade alle Controls selber zeichnet, kriegt man das Verhalten auch nicht geändert. Du willst ja allerdings ein Control nur abrunden. Das sollte gehen. Suche nach runder Button oder rundes Form.
wenn ich "ButtonRenderer.DrawParentBackground(g, ClientRectangle, this);" rausnehme, ist das rechteck dahinter einfach schwarz
Ja, stimmt. Ich hatte nicht bedacht, dass der Bereich aufgrund des Clippings vom dahinterliegenden Control gar nicht erst gezeichnet wird.
herbivore