visual c# draw graphics in front of buttons - c#

I'm working on a winform project (visual c#). One of the forms has many buttons on it and they are located next to each other. I want to add graphics in front of those buttons, in a way the user could keep pressing the buttons. I can't add the graphics behind because the buttons hide the graphics and I don't want to move the buttons. I tried to bring the controls to the back but it didn't work. Any ideas? Thanks!
toPolygon.Insert(toPolygon.Count, button); //insert button to vector
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.Black);
myPen.Width = 10;
System.Drawing.Graphics formGraphics = this.CreateGraphics();
formGraphics.DrawLine(myPen, toPolygon[toPolygon.Count - 2].Location.X, toPolygon[toPolygon.Count - 2].Location.Y,
button.Location.X , button.Location.Y); //draw a line from last button in the vector to the new one
myPen.Dispose();
if (toPolygon.First() == toPolygon.Last())
{
//draw polygon and clean the vector
}

You can do 2 things here, you can do what GuidoG said and make the button image the image you are trying to put over the button or in your form Designer if you click on your button and change it's BackColor to transparent by going to the "Web" tab and then change the "FlatSytle" to be "Flat" and then change the "ForeColor" to be transparent too. That way you will not see the button at all and be able to see everything behind it and still use it as a control.
And if you are trying to draw like lines over the control ect. you will have to overload the "OnPaint" method for that control.
Hope it helps!

Related

C# Label(Transparent backGround) on PictureBox (on Panel)

I want to draw the Labels on PictureBoxes but should be transparent background .
This is my code : `
Labels[i].Location = new Point(0, 0);
Labels[i].Size = new Size(13, 13);
Labels[i].BackColor = Color.Transparent;
Labels[i].ForeColor = Color.Blue;
Invoke(new MethodInvoker(delegate { Panels.Controls.Add(Pictures[i]); }));
Invoke(new MethodInvoker(delegate { Panels.Controls.Add(Labels[i]); }));
I'am drawing my Pictures fine, Labels too ... But I get the Labels under the Pictures (I can see each label when I drag the Picture out of his place)
so I want to know , how I can put them in Front with Transparent BackGround . thank you
`
i think you should use something like z-index
Try calling Panels.Controls[Labels[i].Name].BringToFront(); in your delegate. This should bring each label in front of the pictures since they've already been added to the panel at that point.
I suppose you've already googled for this but here's a good link about winforms transparency.
I used to write many winforms applications that used very ugly skins with transparent labels. As I can remember there was some glitches when used jpg as a background picture and if picture loaded after the label has been drawn.
Anyway, I suggest overriding onPaint and onDraw methods as you can see in the link.
Transparency is only with respect to the container. For this to work you have to add the Label to the PictureBox. Change Panels to the name of the PictureBox you are working with in the Controls.Add() line.

How can I add transparency to a c# form while keeping controls visible?

UPDATE: I took a break from messing with the transparency stuff for a few days. I started messing with it again tonight. I got a new result using Hans Passant's solution:
http://img3.imageshack.us/img3/4265/icontransp.jpg
Passant's solution does solve the issue of the transparent background gradient. However, I'm still running into the problem with the transparent colors in my icon blending with the form's BackColor. You can see the fuchsia around various parts of the icon in the above image.
ORIGINAL CONTENT:
I've been going at this for several hours now, and I haven't had much luck. I've messed with Control.Region, Form.TransparencyKey, Form.Opacity, and a couple other random things with some funky effects.
Lately I've been trying to customize my desktop and decided to mess with Application Docks. After seeing what the Mac dock and a few third-party Windows implementations had to offer, I decided I wanted to build my own.
Eventually I want to move on to using the Win32 API. For now I just want to get something working using as much C# and .Net framework capabilities as possible.
There are a few things I want to be able to do in this application:
Display a form/menu with a gradient background.
Allow the form/menu to have transparency while keeping icons opaque.
Display icons that contain transparent backgrounds.
The Menu and Icons should be able to receive mouse-related events (hover, leave, click, dragover, dragdrop, and a few others).
This is the effect I'm shooting for:
http://img207.imageshack.us/img207/5716/desired.jpg
This image shows the visual effects I'm trying to achieve. This was a skin I made for a program called Rainmeter. The image shows Notepad++ behind the skin with a few of the skin's files open in the editor. The menu is transparent, but the icons remain opaque.
My Approach:
Using a Form to act as the menu seemed like a logical first choice to me. I have a basic understanding of events. I'm not quite sure how to create my own click events, so a form would make working with events a tad easier. I considered a few options for the icons. I decided I'd use PictureBoxes for the icons, since they can hold images and receive events.
Once I finished the code for all the structural logic of my menu, I started playing around with it to try to get the visual effect I wanted. Form.Opacity affected the transparency of everything on the form. Since I want the icons to be fully opaque, I left this property alone. I tried setting the BackColor to Color.Transparent, but that gives an error. I played around with a few combinations...
http://img204.imageshack.us/img204/757/effectsi.jpg
I drew the gradient with a Drawing2D.LinearGradientBrush into a Bitmap. This Bitmap was then placed as the Form.BackgroundImage or as a PictureBox.Image. If used, the PictureBox was sized to cover the entire Form and sent to the back.
I noticed that some of the Form.BackgroundColor would be mixed in with the outlines of my icons. The icons have transparency along the edges for a smoother appearance. Since the icons are picking up the Form's BackgroundColor, this makes me think that the PictureBoxes are creating new images when the icons are loaded into the form. The semi-transparent portions of the image are then merged with the Form's BackgroundColor when they should merge with whatever colors are behind the form.
http://img838.imageshack.us/img838/8299/whitedesktop.jpg
In this image you can see the Fuchsia existing in the icons even though the Form's Fuchsia color is now completely transparent. I forgot to point out that the same green to yellow gradient with an Alpha value of 150 was used in every case. In the images where the gradient doesn't look green, it's because the transparent colors are blending with the Fuchsia background.
I'm not really sure what to do from here. I feel like I could get what I want if I could somehow make the Form alone completely transparent. I was also thinking I may have better luck just drawing the icons instead of using PictureBoxes. The problem then would be setting up the icons to receive mouse events. (I've never made my own events, and I think it would involved some Win32 API calls.)
Is there something else I can do with the PictureBoxes to get the effect I want? Whichever the case, I'm open to any ideas or suggestions for the overall effect I'm trying to achieve.
This is pretty easy to do in Winforms. What you need is a sandwich of two forms. The bottom one should provide the transparent gradient background, the top one should draw the icons and handle mouse clicks. Some sample code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.TransparencyKey = this.BackColor = Color.Fuchsia;
this.Opacity = 0.3;
var overlay = new Form();
overlay.FormBorderStyle = FormBorderStyle.None;
overlay.TransparencyKey = overlay.BackColor = Color.Fuchsia;
overlay.StartPosition = FormStartPosition.Manual;
overlay.Location = this.Location;
overlay.MouseDown += HandleIconClick;
this.Resize += delegate { overlay.Size = this.Size; };
this.LocationChanged += delegate { overlay.Location = this.Location; };
overlay.Paint += PaintIcons;
this.Paint += PaintBackground;
this.Load += delegate { overlay.Show(this); };
}
private void PaintBackground(object sender, PaintEventArgs e) {
var rc = new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height);
using (var br = new LinearGradientBrush(rc, Color.Gainsboro, Color.Yellow, 0f)) {
e.Graphics.FillRectangle(br, rc);
}
}
private void PaintIcons(object sender, PaintEventArgs e) {
e.Graphics.DrawIcon(Properties.Resources.ExampleIcon1, 50, 30);
// etc...
}
void HandleIconClick(object sender, MouseEventArgs e) {
// TODO
}
}
Which looks like this with the somewhat random colors and icon I selected:
OK, I got a bit lost in all that, but from the description in the original paragraph, I would make sure the background rectangle is NOT the visual parent of the pictureboxes. Make them overlapping siblings, with the pictureboxes in front using Panel.Zindex.
Then you can just change the opacity of the rectangle, without affecting the icons. Also make sure the icon source image files have a transparent background.
Should work I think.

Visual Studio C# Windows Forms... changing button color?

I have a form (see screenshot):
As you can see, its a pretty basic form, with a save button. I have programmed it so that if any of the text fields get changed, the "SAVE" button changes color so that its obvious that I haven't clicked save and don't forget to. Unfortunately, simply changing the BackColor of the button to red isn't enough, because its UGLY as sin.
What can I do to change the color of the button to red, but not as ugly. As you can see, the "BackColor" doesn't change the entire button, just the inner piece. The border is still the same old fashioned transparent grey.
A little bit of a LinearGradientBrush can go a long way to soften the harshness of a pure red button.
button1.ForeColor = Color.White;
Bitmap bmp = new Bitmap(button1.Width, button1.Height);
using (Graphics g = Graphics.FromImage(bmp)) {
Rectangle r = new Rectangle(0, 0, bmp.Width, bmp.Height);
using (LinearGradientBrush br = new LinearGradientBrush(
r,
Color.Red,
Color.DarkRed,
LinearGradientMode.Vertical)) {
g.FillRectangle(br, r);
}
}
then you can just assign the image to the button's BackgroundImage property:
button1.BackgroundImage = bmp;
Result:
Note: Assigning a background image will lose the mouse hover coloring of the button.
Another solution would be to add an Icon (e.g. exclamation mark) to the button instead to inform the user that the changes haven't been saved yet.
There are many tutorials online on how to create nice buttons with c#. For example this one allows you to create Vista like buttons. Have a look here: http://www.codeproject.com/Articles/19318/Vista-Style-Button-in-C
For basic colors visit this SO question:
C#: Changing Button BackColor has no effect
You can just use one of the button's properties, "FlatStyle". By default, it is standard. But if you switch it to "Popup", your background color will be extended to the area of the button. You can compare the followings:
left-standard, right-popup
This won't work in WinForms, but you might want to switch over to WPF.
It's much more convenient because you can configure EVERYTHING. (Even the color of a progressbar)
Edit: The OP doesn't have to entirely rewrite his application.
He just needs to redo the layout of it, the code can be C&P'd over to the new WPF project, fyi
Edit²: You don't even need to use code to change the color of a WPF button, you can just define a red overlay with 30% opacity in the XAML file. It's that easy, really.

How do I make a form transparent while keeping the controls fully visible?

I would like to have a form in which the controls on the form are fully visible but the form itself is invisible. If I change the form's Opacity, this makes both the form and the controls on it semi-transparent, so this doesn't work.
I can't do this by setting the form's TransparencyKey, since I have a PictureBox on the form. If the image in the PictureBox happens to contain pixels that match the TransparencyKey, they appear as openings in the form, which I don't want.
TransparencyKey is the only way to get this. Pick the right color. Color.Fuchsia has a long tradition of being the color of choice, going back to the early days of Win32 development. Assault your eye with it to see its merits.
With the caveat that I've never used it, just ran across it once, thought "neat!" and moved on...
Look into System.Drawing.Drawing2D.GraphicsPath and setting the form's Region property. I added two buttons to the basic Windows forms application:
public Form1()
{
InitializeComponent();
Rectangle r1 = new Rectangle(button1.Location, button1.Size);
Rectangle r2 = new Rectangle(button2.Location, button2.Size);
GraphicsPath gp = new GraphicsPath();
gp.AddRectangle(r1);
gp.AddRectangle(r2);
this.Region = new Region(gp);
}
I've approximated the shape of the button with a rectangle; with this code, you can see the form background color at the buttons' corners. You'll need to work out the enclosing path for each of your controls and add them to the path individually. You'll need to take into account any offset introduced by the form title bar or border style.
Update: I did some investigation and have a couple of possible approaches for the problem:
Using the GraphicsPath method, set pictureBox.Visible to False if there is no image loaded.
When you load an image into the picture box, analyze the image to get a list of all the colors in it, then randomly generate one that isn't. Set the form's BackColor and TransparencyKey properties to match this new color, Hans Passant's answer.

Panel of controls over content in the form

Does WinForms have support for this? Let's say I want to show a panel containing ListView made of some results. It is shown by clicking on a button in a form corner, and the panel is shown inside the form, above all controls, preferably with shadow in the back to make it more attractive.
I want this panel to be always inside the form, as a part of it. One solution that comes to my mind is to create a border-less form with that panel, and to make it in sync with original form.
Is there maybe some other way that I'm missing?
Here's a crude method that will get you started:
public Panel CreateFloatingPanel(Panel originalPanel)
{
Bitmap bmp = new Bitmap(originalPanel.Width,
originalPanel.Height);
Rectangle rect = new Rectangle(0, 0,
bmp.Width, bmp.Height);
originalPanel.DrawToBitmap(bmp, rect);
foreach (Control ctrl in originalPanel.Controls)
{
ctrl.Visible = false;
}
using (Graphics g = Graphics.FromHwnd(originalPanel.Handle))
{
g.DrawImage(bmp, 0, 0);
bmp.Dispose();
SolidBrush brush =
new SolidBrush(Color.FromArgb(128, Color.Gray));
g.FillRectangle(brush, rect);
brush.Dispose();
}
Panel floater = new Panel();
floater.Size = originalPanel.Size;
floater.Left = originalPanel.Left - 50;
floater.Top = originalPanel.Top - 50;
this.Controls.Add(floater);
floater.BringToFront();
return floater;
}
This method takes a panel with some controls on it, draws the panel with all its controls onto a temporary bitmap, makes all the controls invisible, draws the temporary bitmap onto the panel, then adds a semi-transparent Gray layer onto the panel. The method then creates a new panel and floats it over the original panel, above and to the left, and then returns it. This basically makes the new panel a sort of modal popup window, kind of like how web pages do it sometimes.
To use this on your form, put all the controls you want to be grayed-out underneath onto a panel, then have your button's Click event do something like this:
Panel floater = CreateFloatingPanel(panel1);
floater.BackColor = Color.White;
ListView lv = new ListView();
floater.Controls.Add(lv);
To undo the effect, you would just remove the floating panel from the form's Controls collection, then make visible again all the controls on the original panel, and then Refresh or Invalidate the panel to get rid of the grayed-out stuff. The simple Invalidate will work because the grayed-out effect does not persist - to get that you'd have to make this all a bit more complicated. But this should get you started, at least.
Could you just create a hidden Panel at the back of the Form, and then make it visible, and then bring it to front?

Categories