Remove extra padding in custom button control - c#

I need some help on removing extra padding around the edges of a custom button control in C#.
The width of this button is 68, and I'd like to keep it that way. If I change it to 70, then the text fits all on one line.
Button control code:
public partial class FlatButton : System.Windows.Forms.Button
{
public FlatButton() : base()
{
FlatAppearance.BorderSize = 0;
FlatStyle = System.Windows.Forms.FlatStyle.Flat;
BackColor = Color.FromArgb(58, 58, 58);
ForeColor = Color.White;
}
protected override bool ShowFocusCues
{
get
{
return false;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Pen pen = new Pen(FlatAppearance.BorderColor, 1);
Rectangle rectangle = new Rectangle(0, 0, Size.Width, Size.Height);
e.Graphics.DrawRectangle(pen, rectangle);
}
public override void NotifyDefault(bool value)
{
}
}
Any ideas on how to remove the extra padding and allow the text to fit all in one line?

Related

(C# Winforms) Drawing a circle on a TextBox

Sorry for my poor English.
I have a user control which includes two text boxes. I wanna draw a circle over that.
I tried to use a transparent panel like below. (This code is from Drawing circles on top of a form)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void DrawCircle(int x, int y, int transparency, Graphics graphics)
{
if (transparency < 0)
transparency = 0;
else if (transparency > 255)
transparency = 255;
Pen pen = new Pen(Color.Red, 5)
graphics.DrawEllipse(pen, new Rectangle(x, y, 90, 90));
pen.Dispose();
graphics.Dispose();
}
private void TransparentPanel1_Paint(object sender, PaintEventArgs e)
{
DrawCircle(10, 10, 255, e.Graphics);
}
private void Form1_Load(object sender, EventArgs e)
{
transparentPanel1.Enabled = false;
transparentPanel1.Paint += TransparentPanel1_Paint;
transparentPanel1.BringToFront();
}
}
public class TransparentPanel : Panel
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//base.OnPaintBackground(e);
}
}
However, it doesn't work.
When I use normal panel rather than transparent panel, the background color covers the entire textbox so I can't see the text. I don't want that.
I don't need editing text when the circle appeared, so this textbox can be replaced with label. (But I still need editing text when the circle doesn't exist.)
How can i draw a circle on a textbox? (Circle can be replaced with 'Circle Image file'. But the background of circle still need to be transparent.)
You can do this by setting the Region property as a ring.
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace WinForm
{
public partial class Form1 : Form
{
TextBox textBox1;
TextBox textBox2;
Panel circle;
public Form1()
{
//InitializeComponent();
textBox1 = new TextBox { Parent = this, Width = 100, Left = 20, Top = 20, Height = 80, AutoSize = false };
textBox2 = new TextBox { Parent = this, Width = 100, Left = 20, Top = textBox1.Bottom };
ShowCircle();
}
void ShowCircle()
{
circle = new Panel
{
Parent = this,
BackColor = Color.Red,
Top = textBox1.Top,
Left = textBox1.Left,
Width = textBox1.Width,
Height = textBox1.Height + textBox2.Height
};
using (var path = new GraphicsPath())
{
var rect = new Rectangle(0, 0, circle.Width, circle.Height);
path.AddEllipse(rect);
rect.Inflate(-5, -5);
path.AddEllipse(rect);
circle.Region = new Region(path);
circle.BringToFront();
}
}
}
}
I have had a similiar problem and the best solution I came up with was to make a screenshot from the parent panel and show the image in a another panel. This panel was made visible while the other one containing all controls was made invisible. I used this to show a loading screen without using a modal form.
I found the code in an old VB.NET application and hope that the translated code works:
class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
internal static Image PrintControl(Control ctrl)
{
using (Graphics controlGraphics = ctrl.CreateGraphics())
{
Bitmap bmp = new Bitmap(ctrl.Size.Width, ctrl.Size.Height, controlGraphics);
using (Graphics bmpGraphics = Graphics.FromImage(bmp))
{
IntPtr dc = bmpGraphics.GetHdc();
PrintWindow(ctrl.Handle, dc, 0);
bmpGraphics.ReleaseHdc(dc);
return bmp;
}
}
}
}
Given you have Panel1 which contains the TextBox controls and Panel2 as a overlay (that contains the screenshot with the red circle) you could use a code like this:
private void ShowRedCircle()
{
Image bmp = NativeMethods.PrintControl(this.panel1);
using (Graphics bmpGraphics = Graphics.FromImage(bmp))
using (Pen sPen = new Pen(Color.Red))
{
bmpGraphics.DrawEllipse(sPen, new Rectangle(10, 10, 90, 90));
this.panel2.BackgroundImage = bmp;
}
this.panel2.Visible = true;
this.panel1.Visible = false;
}
When you want to remove the circle just change the visibility of the panels again. You should consider to dispose the BackgroundImage of panel2 in this case.

Transparent control over drew shape

I'm new for create user control, and in my first usercontrol i used from picturebox and label ,
picturebox for draw a shape and label for show text over that shape.
i was set picturebox parent for label, and label backcolor to transparent also if don't have any text label set to visible = false
now i have a problem, when label is visible, i can't see picturebox correctly.
how can i solve this problem ?
also paint event on user control not work
private void Ucontrol_Paint(object sender, PaintEventArgs e)
{
if (RightToLeft)
{
lblTxt.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
}
else
{
lblTxt.RightToLeft = System.Windows.Forms.RightToLeft.No;
}
lblTxt.ForeColor = FontColor;
lblTxt.Text = Txt;
if (Question)
{
BorderColor = Color.DarkBlue;
BackColor = Color.FromArgb(75, 163, 234);
CreateQuestion(BorderColor, BackColor);
}
else
{
BorderColor = Color.DarkGreen;
BackColor = Color.FromArgb(59, 226, 75);
CreateAnswer(BorderColor, BackColor);
}
}
Forms controls don't have really a transpartent background, they copy it's parent content.
Also, a PictureBox can't be parent of another control as they aren't container.
Then, instead of using a picturebox just set the usercontrol background image and put the label on it, the transparency should work.
Here is a working example manually drawing the control content:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Label lbl = new Label();
lbl.Location = new Point(10, 10);
lbl.Width = 150;
lbl.Height = 150;
lbl.BackColor = Color.Transparent;
lbl.Text = #"asdfasdfasdfasdf\r\nasdfasdfasdf\r\n\r\nasdfasdfasdf";
lbl.Visible = true;
this.Controls.Add(lbl);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(Brushes.Red, new Rectangle(10, 10, 100, 100));
e.Graphics.FillEllipse(Brushes.Yellow, new Rectangle(10, 10, 100, 100));
}
}

Painting a TextBox

I'm in need of a way to make TextBox appear like a parallelogram but i can't figure out how to do so. I currently have this code:
private void IOBox_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Point cursor = PointToClient(Cursor.Position);
Point[] points = { cursor, new Point(cursor.X + 50, cursor.Y), new Point(cursor.X + 30, cursor.Y - 20),
new Point(cursor.X - 20, cursor.Y - 20) };
Pen pen = new Pen(SystemColors.MenuHighlight, 2);
g.DrawLines(pen, points);
}
But apparently it's not working. Either i misplaced/misused it or i'm not doing something right.
This is the method that i use to add it.
int IOCounter = 0;
private void inputOutput_Click(object sender, EventArgs e)
{
IOBox box = new IOBox();
box.Name = "IOBox" + IOCounter;
IOCounter++;
box.Location = PointToClient(Cursor.Position);
this.Controls.Add(box);
}
Any idea how i can fix it? IOBox is a UserControl made by me which contains a TextBox. Is that rightful to do?
If its possible, you should make your application using WPF. WPF is designed to do exactly what you are trying to do.
However, it can be done in WinForms, though not easily. You will need to make a new class that inherits the TextBox WinForm control. Here is an example that makes a TextBox look like a circle:
public class MyTextBox : TextBox
{
public MyTextBox() : base()
{
SetStyle(ControlStyles.UserPaint, true);
Multiline = true;
Width = 130;
Height = 119;
}
public override sealed bool Multiline
{
get { return base.Multiline; }
set { base.Multiline = value; }
}
protected override void OnPaintBackground(PaintEventArgs e)
{
var buttonPath = new System.Drawing.Drawing2D.GraphicsPath();
var newRectangle = ClientRectangle;
newRectangle.Inflate(-10, -10);
e.Graphics.DrawEllipse(System.Drawing.Pens.Black, newRectangle);
newRectangle.Inflate(1, 1);
buttonPath.AddEllipse(newRectangle);
Region = new System.Drawing.Region(buttonPath);
base.OnPaintBackground(e);
}
}
Keep in mind that you will still have to do other things, such as clipping the text, etc. But this should get you started.

OnPaint Paint Issue

I have created a custom checkBox to increase the height of the rectangle of the checkbox. I have override the OnPaint method as given below. When I make the control transparent, background becomes white, instead of transparent. What could be the issue?
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
int h = this.Height;
if (BackColor == Color.Transparent)
{
pevent.Graphics.Clear(this.Parent.BackColor);
}
else
{
pevent.Graphics.Clear(BackColor);
}
Rectangle rc = new Rectangle(new Point(0, 0), new Size(h, h));
ControlPaint.DrawCheckBox(pevent.Graphics, rc,
this.Checked ? ButtonState.Checked : ButtonState.Normal);
SizeF stringMeasure = pevent.Graphics.MeasureString(Text, Font);
int topOffset = (int)(ClientRectangle.Height - stringMeasure.Height) / 2;
pevent.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), this.Height, topOffset);
}
I am not sure if you derived your checkbox from the given class CheckBox or you derived it from Control. If you derived from control, you should add in the constructor the following line:
public CustomChecBox()
: base()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
Note, that there is also a function called OnPaintBackground(...) which you can override, but you should not need to to this.
In your OnPaint()-function, you should replace
if (BackColor == Color.Transparent)
{
pevent.Graphics.Clear(this.Parent.BackColor);
}
else
{
pevent.Graphics.Clear(BackColor);
}
with
pevent.Graphics.Clear(BackColor);
or
pevent.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
But this is, what happens in OnPaintBackground(...). If you set the BackColor to transparent and you added the SetStyle-Methid in the contructor, then your control should be really transparent. I hope this helps.

Customize ToolStripMenuItem

I want to customize ToolStripMenuItem by overriding OnPaint function. This is a MyToolStripMenuItem:
public class MyToolStripMenuItem : ToolStripMenuItem
{
public MyToolStripMenuItem()
:base()
{
}
public MyToolStripMenuItem(string t)
:base(t)
{
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle r = this.Bounds;
g.FillRectangle(Brushes.Blue, r);
g.DrawString(this.Text, this.Font, Brushes.Red, r);
}
}
In my code, I will fill a blue color in item's bound. Now, I will create a list of items on menustrip:
MyToolStripMenuItem1
|___MyToolStripMenuItem2
|___MyToolStripMenuItem3
I don't know why MyToolStripMenuItem3 don't have a blue background.
This is my source code:
http://www.mediafire.com/?2qhmjzzfzzn
Please help me. Thanks.
It's not the way it is done with a ToolStripMenuItem. You give the MenuStrip a custom renderer. For example:
For example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
menuStrip1.Renderer = new MyRenderer();
}
private class MyRenderer : ToolStripProfessionalRenderer {
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) {
if (!e.Item.Selected) base.OnRenderMenuItemBackground(e);
else {
Rectangle rc = new Rectangle(Point.Empty, e.Item.Size);
e.Graphics.FillRectangle(Brushes.Beige, rc);
e.Graphics.DrawRectangle(Pens.Black, 1, 0, rc.Width - 2, rc.Height - 1);
}
}
}
}
The problem with using OnRenderMenuItemBackground() is that it applies to the whole menu and not just the one ToolStripMenuItem.
The error in the code lies in Rectangle r = this.Bounds; which produces the wrong area. Change this to Rectangle r = e.ClipRectangle and it should work ok. (For some reason the Bounds has the wrong Y component).

Categories