I used this answer: Alpha in ForeColor
to create a custom label element that allowed fading through ARGB unlike the default label.
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyLabel : Label {
protected override void OnPaint(PaintEventArgs e) {
Rectangle rc = this.ClientRectangle;
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic);
using (var br = new SolidBrush(this.ForeColor)) {
e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt);
}
}
}
I was curious how I would implement TextAlign into this class allowing the text contents to be aligned correctly.
Thanks to #Aybe's comment, I worked out I needed to add the Alignment to the StringFormat var fmt like this:
fmt.Alignment = StringAlignment.Center;
Making the entire class look like this:
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyLabel : Label {
protected override void OnPaint(PaintEventArgs e) {
Rectangle rc = this.ClientRectangle;
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic);
fmt.Alignment = StringAlignment.Center;
using (var br = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt);
}
}
}
Related
I have been experiencing an issue with my custom TabControl. I cannot remove a Border from the TabControl.
Here is the code of the TabControl.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Windows.Forms;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;
namespace GoatUserControls
{
public partial class GoatTab : TabControl
{
public static bool N_PositionMode;
public static bool N_PlusButton;
public GoatTab()
{
DrawMode = TabDrawMode.OwnerDrawFixed;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
DoubleBuffered = true;
SizeMode = TabSizeMode.Fixed;
ItemSize = new System.Drawing.Size(120, 30);
N_PositionMode = false;
N_PlusButton = false;
this.DrawMode = TabDrawMode.OwnerDrawFixed;
SetWindowTheme(this.Handle, "", "");
//var tab = new TabPadding(this);
}
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
//All Properties
[Description("Desides if the Tab Control will display in vertical mode."), Category("Design"), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public bool VerticalMode{ get { return N_PositionMode; } set { N_PositionMode = value; if (N_PositionMode == true) { SetToVerticalMode(); } if (N_PositionMode == false) { SetToHorrizontalMode(); } }}
//Method for all of the properties
private void SetToHorrizontalMode(){ ItemSize = new System.Drawing.Size(120, 30); this.Alignment = TabAlignment.Top; }
private void SetToVerticalMode(){ ItemSize = new System.Drawing.Size(30, 120); Alignment = TabAlignment.Left; }
protected override void CreateHandle()
{
base.CreateHandle();
Alignment = TabAlignment.Top;
}
protected override void OnPaint(PaintEventArgs e)
{
Bitmap B = new Bitmap(Width, Height);
Graphics G = Graphics.FromImage(B);
G.Clear(Color.Gainsboro);
Color NonSelected = Color.FromArgb(62, 62, 62);
Color Selected = Color.FromArgb(0, 172, 219);
SolidBrush NOSelect = new SolidBrush(NonSelected);
SolidBrush ISSelect = new SolidBrush(Selected);
for (int i = 0; i <= TabCount - 1; i++)
{
Rectangle TabRectangle = GetTabRect(i);
if (i == SelectedIndex)
{
//Tab is selected
G.FillRectangle(ISSelect, TabRectangle);
}
else
{
//Tab is not selected
G.FillRectangle(NOSelect, TabRectangle);
}
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
Font font = new Font("Segoe UI", 10.0f);
G.DrawString(TabPages[i].Text, font, Brushes.White, TabRectangle, sf);
TabPages[i].BackColor = Color.FromArgb(62, 62, 62);
//TabPages[i].Padding = Point(0, 0);
}
e.Graphics.DrawImage(B, 0, 0);
G.Dispose();
B.Dispose();
base.OnPaint(e);
}
}
}
I think the Border is a background of the control. So most likely the question is how can I remove the background of a control. Do you guys have any ideas?
I used an advise from this topic: Rounded edges in picturebox C# to make my picturebox edges rounded. So, I claimed a new control using this code:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
class OvalPictureBox : PictureBox {
public OvalPictureBox() {
this.BackColor = Color.DarkGray;
}
protected override void OnResize(EventArgs e) {
base.OnResize(e);
using (var gp = new GraphicsPath()) {
gp.AddEllipse(new Rectangle(0, 0, this.Width-1, this.Height-1));
this.Region = new Region(gp);
}
}
}
But there is my question: how could I add antialias to my control? I read some topics like this: Possible to have anti-aliasing when drawing a clipped image? but there is just drawing functions are used, and I need to implement antialias in my own control, which parent is PictureBox.
I also tried to override OnPaint method to get PaintEventArgs to use the SmoothingMode, but my code sucked and didn`t work properly.
So I deleted it and this is what I have now:
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
using (var gp = new GraphicsPath())
{
gp.AddEllipse(new Rectangle(0, 0, this.Width - 1, this.Height - 1));
this.Region = new Region(gp);
}
}
What should I add to this method?
I want to create a Picturebox that adapts its shape to a string of a certain Font. I need this so that I can later create texts and lay it over an AxWindowsMediaPlayer control.
Therefore I created the following class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace myProject
{
class ShapedPictureBoxes : PictureBox
{
public ShapedPictureBoxes()
{
this.Paint += this.shapedPaint;
}
void shapedPaint(object sender, PaintEventArgs e)
{
System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
Font font = new Font("Arial", 14f);
float emSize = e.Graphics.DpiY*font.Size/72;
graphicsPath.AddString(text, new FontFamily("Arial"), (int)System.Drawing.FontStyle.Regular, emSize, new Point(0,0), new StringFormat());
e.Graphics.DrawString(text, font, Brushes.Red, new Point(0, 0));
this.Region = new Region(graphicsPath);
}
public string text = "Here comes the sun, doo da doo do";
}
}
The problem now is, that the "Graphics.DrawString" does not match the graphicspath.AddString, probably because FontFamily isn't the same as Font. How can I match them?
So: How can I convert Fontfamily to Font or viceversa?
This is how it looks like:
You need to account for the fact that the Font size is specified in units of points, but the AddString() size is specified in device units.
You can convert the units as follows:
Font font = new Font("Arial", 14f, FontStyle.Bold);
float emSize = e.Graphics.DpiY * font.Size / 72; // Here's the conversion.
graphicsPath.AddString(text, new FontFamily("Arial"), (int)System.Drawing.FontStyle.Bold, emSize, new Point(0, 0), new StringFormat());
Note that I'm passing the calculated emSize to AddString() instead of passing 14f.
I just need to know how I can load a font file and get the characters in an array of data and then call one particular character.
var families = Fonts.GetFontFamilies(#"C:\WINDOWS\Fonts\Arial.TTF");
foreach (FontFamily family in families)
{
}
Hopefully this will give you the idea (untested). Take care to use using or explicitly dispose your graphics objects:
using System.Drawing;
using System.Drawing.Imaging;
...
// Create your bitmap - 100x100 pixels for example
using (Bitmap b = new Bitmap(100, 100))
{
using (Graphics g = Graphics.FromImage(b))
{
g.Clear(Color.White); // White background
using (FontFamily fontFamily = new FontFamily("Arial"))
{
using (Font font = new Font(fontFamily, 24, FontStyle.Regular, GraphicsUnit.Pixel))
{
using (SolidBrush solidBrush = new SolidBrush(Color.Red)) // Red text
{
g.DrawString("A", font, solidBrush, new PointF(10, 10)); // Draw an "A" at position 10,10
}
}
}
}
b.Save(Response.OutputStream, ImageFormat.Jpeg); // return to response, for example
}
}
I am new to Dot Net, I want to print a rectangle with 20mm width and 8mm height exactly if I measure with scale. I also want to print text exactly in the middle of rectangle.Can anyone suggest me how can I achieve this?
I am really sorry for not being clear earlier. I have tried using "PageUnits" its working fine. However, I have problem with the margins.
I am able to print correct margins(8.8mm left and 22mm Top) if I am using the printer "HP LaserJet P2035n". If print using "Canon iR2020 PCL5e" I am getting incorrect margins(8.1mm left and 8.0mm Top) where I should get 8.8mm left and 22mm top margins. Can someone explain me where I am doing wrong.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Printing;
namespace ConsoleApplication6
{
class DrawShape
{
public static void DrawRec()
{
PrintDocument doc = new PrintDocument();
doc.PrintPage += doc_PrintPage;
doc.Print();
}
static void doc_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
PageSettings PageSet = new PageSettings();
float MarginX = PageSet.PrintableArea.X;
float MarginY = PageSet.PrintableArea.Y;
float x = (float)(8.8-((MarginX/100)*25.4));
float y = (float)(22-((MarginY/100)*25.4));
g.PageUnit = GraphicsUnit.Millimeter;
g.DrawRectangle(Pens.Black, x, y, 20, 8);
}
}
}
You may want to start with this:
private void button1_Click(object sender, EventArgs e)
{
using (Graphics formGraphics = this.CreateGraphics())
{
formGraphics.PageUnit = GraphicsUnit.Millimeter;
formGraphics.DrawRectangle(Pens.Blue, 0, 0, 20, 80);
}
}
You can then using DrawString on the Graphics object to draw text inside your rectangle.