The standard way of g.DrawString creates a gray background. So if overlay another string on the form, part of it appears gray.
My question is, is there any way to draw a string with a transparent background? i want to be able to overlay strings, but still be able to see them.
Are you sure?
Here's a tutorial, which might help:
http://www.switchonthecode.com/tutorials/csharp-snippet-tutorial-how-to-draw-text-on-an-image
(edit)
Try starting from basics: I just created a new forms application and changed the code in Form1 to this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Paint += new PaintEventHandler(Form1_Paint);
}
void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString("hello", new Font("Arial", 36), new SolidBrush(Color.FromArgb(255,0,0)), new Point(20,20));
e.Graphics.DrawString("world", new Font("Arial", 36), new SolidBrush(Color.FromArgb(0,0,255)), new Point(30,30));
}
}
It works as expected, with a transparent background for the text.
This is impossible to diagnose without you posting code. By default, Graphics.DrawString does not paint the background. This sample form demonstrates this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.DrawString("Underneath", this.Font, Brushes.Black, 0, 0);
e.Graphics.DrawString("Overlap", this.Font, Brushes.Black, 25, 5);
base.OnPaint(e);
}
}
Note how the 'Overlap' string does not erase the 'Underneath' string.
Related
Okay so I have created a Flowlayoutpanel in which about 70 usercontrols, all squares of 50x50 pixels with an animated grass gif inside a picturebox inside of it. I want to make these hide-able but not be removed so there's a white space left. I've been able to do that quite consistently by just using Hide() and changing the background colour to be transparant so I don't have to hide the entire UserControl.
Problem comes up here, I want these gifs to reappear on a timer, so I've created a timer that references a method which just uses a show() again to show said gif and yet it refuses to do so if I create a seperate button to do so or not.
I have searched quite a bit but I think this is a problem only because I'm consistently missing something in my code so no other question really seems to answer my troubles. Because it's such a simple question I feel kind of embarrassed even asking it but oh well.
This is the timer event that calls the method in the other class
private void GrasTerugkeerTimer_Tick(object sender, EventArgs e)
{
var instance = new GrasVeldUC();
instance.TerugKeerGras();
}
This is the events and methods I've set up to show and hide the picturebox that the gif is inside of
public partial class GrasVeldUC : UserControl
{
public GrasVeldUC()
{
InitializeComponent();
this.BackColor = Color.White;
}
private void GrasVeldUC_Click(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 255, 255, 255);
PIBGrasUC.Hide();
}
private void PIBGrasUC_Click(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 255, 255, 255);
PIBGrasUC.Hide();
}
public void TerugKeerGras()
{
this.BackColor = Color.FromArgb(100, 255, 255, 255);
PIBGrasUC.Show();
}
}
Now I expected this to just work and just show the picturebox again and yet whatever I tried, creating a seperate method that references the method in the other class, it would not work. And the method in the class "GrasVeldUC" does work I put a messagebox inside of it to test and it worked perfectly.
You can just toggle the picturebox.visible as needed.
I am new to WinForms, so need your expert advice on this issue that I am facing when I deploy my Winform Application in Window 10 Pro environment. I see that the dialog form which has FormBorderStyle set to SizableToolWindow(or FixedToolWindow for that matter) doesnt paint the Borders on all side on the window except on top.
Border Issue when FormBorderStyle is set to SizableToolWindow
Border is seen when FormBorderStyle is set to FixedSingle
Sample Complete Code is given below:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form form = new Form();
form.FormBorderStyle = FormBorderStyle.FixedSingle;
form.ShowDialog();
}
}
Is there a solution which can override this behavior maybe just for windows 10?
EDIT: I observed that when I set the ControlBox Property of the Form to false the client site is only shown and has the complete border but then the Caption bar is not visible.
Well, I would say the behavior and the rendering depends on the operating system and I think there is no real answer to your question.
However, you can create custom form/window and you can use it as a tool window or however you want.
First, you would need to set the FormBorderStyle to None
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Then you can override the OnPaint method and draw your border there like the code below
protected override void OnPaint(PaintEventArgs e)
{
Rectangle borderRectangle = new Rectangle(1, 1, ClientRectangle.Width - 2, ClientRectangle.Height - 2);
e.Graphics.DrawRectangle(Pens.Blue, borderRectangle);
base.OnPaint(e);
}
The outcome would be something like in the image below:
Please note that you will have to take care of other things like giving the ability to this form to be moved around, make sure you add custom close button etc.
Once you have this done, you can use this form as a base class and inherit your future form classes from that one.
The complete code of that custom form would be:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CustomForm
{
public partial class CustomBorderForm : Form
{
public CustomBorderForm()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle borderRectangle = new Rectangle(1, 1, ClientRectangle.Width - 2, ClientRectangle.Height - 2);
e.Graphics.DrawRectangle(Pens.Blue, borderRectangle);
base.OnPaint(e);
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
I hope this was helpful.
My form has a background image. I have some pictureBoxes i am using as buttons. I am attempting to have a MouseEnter/MouseLeave event to display label or pictureBox.
I have been trying various approaches. I am getting similar results- The label or picturebox appears fine, but on MouseLeave, label1.Visible = false; causes a very temporary blank box over the background image of the form. While it is fully functional, it just seems like a very slight lag, but makes the program look bad.
I experimented with the DrawString method. This seems like it could be a good option, but i cannot figure out how to remove the object on a MouseLeave event.
Is this possible? If not, is there a better option to accomplish what i am trying to accomplish?
Here is how I am drawing my string (in buttonClick event for testing):
Graphics g = this.CreateGraphics();
string letter = "Yo Dawg!";
g.DrawString(letter, new Font(FontFamily.GenericSansSerif, 20, FontStyle.Regular),
new SolidBrush(Color.Black), 100, 100);
You would draw in the paint event, in MouseLeave set a flag, cause a paint with Invalidate() then within paint if the flag is not set don't draw anything.
public partial class TheForm : Form
{
private Font _font = new Font(FontFamily.GenericSansSerif, 20, FontStyle.Regular);
private bool _hovering = false;
public TheForm() {
InitializeComponent();
picBox.Paint += new PaintEventHandler(picBox_Paint);
picBox.MouseEnter += (sender, e) => UpdateText(true);
picBox.MouseLeave += (sender, e) => UpdateText(false);
}
private void picBox_Paint(object sender, PaintEventArgs e) {
if (_hovering)
e.Graphics.DrawString("Yo Dawg!", _font, Brushes.Black, 100, 100);
}
private void UpdateText(bool show) {
_hovering = show;
picBox.Invalidate();
}
}
I have a project in c# with many forms. Imagine this scenario:
Every form has a (let's say green) rectangle in it. when I call a function, i need every rectangle to change it's color (to red). I have created this function in order to draw a rectangle:
private void drawBorder(System.Drawing.Color c)
{
System.Drawing.Graphics g = this.CreateGraphics();
System.Drawing.Brush br = new System.Drawing.SolidBrush(c);
System.Drawing.Pen p = new System.Drawing.Pen(br, 4);
System.Drawing.Rectangle r = new Rectangle(0, 0, 50, 50);
g.DrawRectangle(p, r);
g.Dispose();
br.Dispose();
p.Dispose();
}
I have realized that I cannot call this function on load (is this true?) This just was my first question needing an answer
So, if i had just one form, I would first call this function on paint:
private void fLogin_Paint(object sender, PaintEventArgs e)
{
drawBorder(System.Drawing.Color.Red);
}
and then call it again whenever I need (eg on a button click) with a different color argument. This works on my single form. But I need this in every form.
So my second question is do i need to create a _paint event in every form for my solution to work?
I have also thought that i could create a new type of Form, inheriting the default form, add the _paint event in that form and define all my forms as this type. Which is the best approach?
My last question is: When i call my function more than once, what I really do is drawing a new rectangle on top of the previous one. Should i use
this.Invalidate();
before changing the color of my border?
A base form is a solid approach - add to that a static method to trigger a static event when you want to change the colour.
Make your base form handle that event and force a repaint and you should have a single point from where all rectangles can changed.
Well I would suggest you to create a BaseForm with protected override OnPaint().
And whenever you create a new Form, inherit the BaseForm instead of the default Form
Here is how you do BaseForm
public class BaseForm : Form
{
protected void DrawBorder(Color c)
{
var g = CreateGraphics();
var br = new SolidBrush(c);
var p = new Pen(br, 4);
var r = new Rectangle(0, 0, 50, 50);
g.DrawRectangle(p, r);
p.Dispose();
br.Dispose();
g.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
DrawBorder(Color.Red);
base.OnPaint(e);
}
}
How to apply it on new created form
public partial class Form1 : BaseForm // Use the BaseForm instead of default 'Form'
{
public Form1()
{
InitializeComponent();
}
}
I'm trying to draw a text on a panel(The panel has a background picture).
It works brilliant,but when I minimize and then maximize the application the text is gone.
My code:
using (Graphics gfx = Panel1.CreateGraphics())
{
gfx.DrawString("a", new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
}
How do I keep it static so it doesn't get lost?
Inherit from Panel, add a property that represents the text you need to write, and override the OnPaintMethod():
public class MyPanel : Panel
{
public string TextToRender
{
get;
set;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawString(this.TextToRender, new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
}
}
This way, each Panel will know what it needs to render, and will know how to paint itself.
Just add a handler for the Paint event:
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString("a", new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
}
If you don't use a Paint event, you are just drawing on the screen where the control happens to be. The control is not aware of this, so it has no idea that you intended for the text to stay there...
If you put the value that you want drawn on the panel in it's Tag property, you can use the same paint event handler for all the panels.
Also, you need to dispose of the Font object properly, or you will be having a lot of them waiting to be finalized before they return their resources to the system.
private void panel1_Paint(object sender, PaintEventArgs e) {
Control c = sender as Control;
using (Font f = new Font("Tahoma", 5)) {
e.Graphics.DrawString(c.Tag.ToString(), f, Brushes.White, new PointF(1, 1));
}
}
When you draw something, it only remains until the next time the form is refreshed.
When the form is refreshed, the Paint event is called. So if you want to ensure your text doesn't disappear, you need to include the code that draws it in the Paint event.
You can trigger a repaint using Control.Invalidate, but you otherwise cannot predict when they will happen.