I am trying to create a 'jeopardy' type game and i have gotten to the point where you just have to click on a box and a question box will appear.
Im using a customPictureBox, essentially overriding text and such:
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Size size = TextRenderer.MeasureText(text, font);
int x = Width / 2 - size.Width / 2;
int y = Height / 2 - size.Height / 2;
pe.Graphics.DrawString(text, font, new SolidBrush(color), x, y);
}
on the game i add its properties like this:
CustomPictureBox box = new CustomPictureBox()
{
Text = ((QuestionBox)sender).Question.Text.ToUpper(),
SizeMode = PictureBoxSizeMode.StretchImage,
Font = new Font("Comic Sans MS", 40),
Image = Properties.Resources.MainTile,
ForeColor = Color.White,
BorderStyle = BorderStyle.FixedSingle,
Dock = DockStyle.Fill
};
The problem comes when the text length exceeds certain amount of (depending on the monitor) words, essentially what happens is that the text is drawn but a majority of it goes outside of the form, adding Autosize and Maximum size
Reference, this adds the MaxSize to the whole CustomPictureBox.
This solution seems to put an offset for the words, making longer sentences fly completely off the screen.
Ideally I need to add a newline til the words reach a preset boundary so they wouldn't go off the form.
Do not use Graphics.DrawString, use TextRenderer.DrawText instead.
Specifically, use this overload since it accepts
IDeviceContext - that's your Graphics instance,
String - that's the string to draw,
Font - that's the font to use,
Rectangle - that's the rectangle to use for boundaries,
Color - that's the fore color to use,
And TextFormatFlags - that's a flags enum that allows you to specify how to wrap text - using either default or WordBreak.
So, replace this row:
pe.Graphics.DrawString(text, font, new SolidBrush(color), x, y);
With this:
var flags = TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter |
TextFormatFlags.WordBreak;
TextRenderer.DrawText(pe.Graphics, text, font, pe.ClipRectangle, ForeColor, flags);
Related
I am trying to make all check boxes in my C# Winform application to ignore user's DPI setting when it's bigger than 100%.
i.e I want the size of the checkbox to remain small as if it's on 100% font scale, even when the user has increased the DPI setting.
Using FlatStyle.Flat checkboxes, the size of the checkboxes in various DPI settings:
100% (96 DPI) : 11 pixel x 11 pixel (including border)
125% (120 DPI) : 13 x 13
150% (144 DPI) : 16 x 16
I have done the following but the size of my checkboxes still increases:
AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
set all Font to use GraphicsUnit.Pixel
So, is there a way for my checkbox to remain 11pixel by 11pixel regardless of DPI setting?
If it's not possible, I have also tried overriding OnPaint on my custom checkbox to paint over the checkbox without painting over the Text.
But it proves to be complicated since the starting (X,Y) coordinate to render the box is somewhat affected by CheckAlign and RightToLeft properties.
This is the code snippet.
I intended for red box to paint over the original checkbox.
And green box as the new checkbox I want to display instead.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// We need to override checkbox drawing for large font scaling since it will be drawn bigger than usual.
// ex: At 100% scaling, checkbox size is 11x11. At 125% scaling, checkbox size is 13x13.
if (e.Graphics.DpiX > 96)
{
// What is the x & y co-ords of the checkbox?
int x = 0;
int y = 0;
using (SolidBrush brush = new SolidBrush(Enabled ? Color.White : SystemColors.Control))
{
// Red checkbox is to override the original checkbox drawn
var scaleFactor = e.Graphics.DpiX / 96;
e.Graphics.DrawRectangle(new Pen(Color.Red), x, y, (float)Math.Round(CHECKBOX_WIDTH * scaleFactor) + 1, (float)Math.Round(CHECKBOX_HEIGHT * scaleFactor) + 1);
// Green checkbox is to draw the small checkbox that I want 11x11 (including border)
e.Graphics.FillRectangle(brush, x, y, CHECKBOX_WIDTH, CHECKBOX_HEIGHT);
e.Graphics.DrawRectangle(new Pen(Color.Green), x, y, CHECKBOX_WIDTH + 1, CHECKBOX_HEIGHT + 1); // Draw the outer border
}
}
}
Can anyone help me how to determine the correct X,Y coord for me to draw the red checkbox, please (so I can paint over the original box).
Thank you :)
I am trying to insert a text watermark underneath a TIFF image in my windows form and would definitely appreciate anyone's help. I have a print button that retrieves the image, scales it down, then based on my margins, places the image accordingly to print. I'd like to add an additional piece where just before the image prints, I add in a text watermark (in this case a date stamp) that is just below the image.
I've tried adjusting the margin but that just increases (or decreases depending on the number setting) the image scale but does not add the additional room I want to add the watermark. Below is code of what I have so far:
protected void PrintPage(object sender, PrintPageEventArgs e)
{
if (this.Image == null)
{
e.Cancel = true;
return;
}
//ADD TIME STAMP WATERMARK
string watermark = "DATE ISSUED: " + String.Format("{0:MM/dd/yyyy}", System.DateTime.Now.Date);
System.Drawing.Graphics gpr = Graphics.FromImage(Image);
System.Drawing.Brush brush = new SolidBrush(System.Drawing.Color.Black);
Font font = new System.Drawing.Font("Arial", 55, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
SizeF size = e.Graphics.MeasureString(watermark, font);
float x = 0;
float y = Image.Height-size.Height;
RectangleF printArea = new RectangleF(x, y, size.Width, size.Height);
gpr.DrawString(watermark, font, brush, printArea);
e.Graphics.DrawImage(this.Image, e.MarginBounds);
}
The value of e.MarginBounds I have set in my App.config and include the following values: Left=70, Right=90, Top=190; Bottom=475. All the printouts are going to be printed portrait style on Letter 8 1/2 by 11 size paper.
I am able to display the watermark anywhere on top of the image, but I am hoping to place it underneath. When I adjust the y coordinate, and it so happens to be below the image, when I print, I assume that it is outside the print area and therefore, the watermark does not get printed on the page (it only shows the image).
I appreciate anyone's help in this as I have been racking my brain on this and have had no luck.
Aren't you printing your text beneath the image. I think you want to start printing at y=Image.Height + e.MarginBounds.Top, and x=e.MarginBounds.Left
That will print a your label left justified below the image in the margin.
Update: This works:
y=-size.Height + e.MarginBounds.Bottom;
x = e.MarginBounds.Left;
e.Graphics.DrawImage(Image, e.MarginBounds);
// note the change. Using e.graphics instead of gpr below
e.Graphics.DrawString(watermark, font, brush, printArea);
I'm using this method to draw the text on form1:
private bool DrawText(bool draw, string texttodraw)
{
Graphics g = this.CreateGraphics();
SizeF size = g.MeasureString(texttodraw, SystemFonts.DefaultFont,14);
g.DrawString(texttodraw, Font, Brushes.Red, pictureBox1.Location.X + (pictureBox1.Width / 2) - (size.Width / 2),
pictureBox1.Location.Y - 30);
return draw;
}
I tried to set Width to 14 on the SizeF size lline but it didn't change the dize and the only thing it did is moving a bit the text from it's location .
How can i change the font size of the text, and also to keep the perspective(if this is the right word to use) of the text location ?
This is how it look like when not using the Width 14 at all the text is in the center above the pictureBox1. I want that when i change the text size it will be kept to be in the center like it is now.
The text is in Red and it's in hebrew in this case.
Try using a bigger font:
using (Font bigFont = new Font(SystemFonts.DefaultFont.FontFamily, 14, FontStyle.Regular)) {
SizeF size = g.MeasureString(texttodraw, bigFont, 14);
g.DrawString(texttodraw, bigFont, Brushes.Red, pictureBox1.Location.X + (pictureBox1.Width / 2) - (size.Width / 2),
pictureBox1.Location.Y - 30);
}
Do avoid using CreateGraphics, it's only a temporary drawing that will get erased by overlapping windows or minimizing the form. It will also cause flicker. Use the graphics object from the paint event and invalidate the control to update the painting.
Also, do favor using TextRenderer.DrawText and TextRenderer.MeasureText for your text renderings. DrawString should primarily be used for printing to paper.
I think the best way is to use StringFormat object to center-align the text either horizontally or vertically or both using the 5th overload of Graphics.DrawString() funciton:
You need to provide a Rectangle objet and alignment is done with respect to this object.
StringFormat sf=new StringFormat();
sf.LineAlignment = StringAlignment.Center;//center-align vertically
sf.Alignment = StringAlignment.Center; //center-align horizontally
private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Font drawFont = new Font("Arial Black", 9);
e.Graphics.DrawString(nic.Text, drawFont, Brushes.Maroon, 174, 12);
I have two problems with the GroupBox, they appears after setting GroupBox.AutoSizeMode = AutoSizeMode.GrowAndShrink and GroupBox.AutoSize = true.
GroupBox.Text width is not taken into account at all. Sizing will occurs to fit content only and then text will get wrapped if it doesn't fit. If it cannot fit - it is simply not displayed.
There is unnecessarily big gap between bottom of the GroupBox and Label inside.
Questions:
How to make GroupBox respecting its Text property when autosizing? And how to remove that gap?
For some reasons my previous question gets on hold. Should I delete it or what?
P.S.: if you are putting on hold or something, please comment what is exactly not-clear in what I am asking!
/*
Calculate the Text Width in pixels, then set the size for the GroupBox.
*/
groupBoxA.SuspendLayout();
SizeF stringSizeLabel;
using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1)))
{
Font stringFont = new Font("Microsoft Sans Serif", 8.25F);
stringSizeLabel = graphics.MeasureString("SAMPLE TEXT", stringFont);
}
int iWidth = (int)(stringSizeLabel.Width * 1.35f); // Give a little extra width
int iHeight = 78; // This is a sample value
groupBoxA.Size = new System.Drawing.Size(iWidth, iHeight);
groupBoxA.MinimumSize = new System.Drawing.Size(iWidth, iHeight);
groupBoxA.ResumeLayout(false);
groupBoxA.PerformLayout();
I have the following code:
public void DrawLetter(int Cell, string Letter, int X, int Y)
{
System.Drawing.Font fBody = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
Pencil.DrawString(Letter, fBody, System.Drawing.Brushes.Black, X, Y);
Pencil.DrawRectangle(new Pen(System.Drawing.Brushes.Red), X, Y, 10, 10);
}
When I go through this twice and use 140,249 and 296,249 as co-ordinates the rectangle appears as I would expect in the correct position but the string appears a few pixels out and I can't work out why.
I put in the DrawRectangle to check that it was starting in the correct position and it is. Am I doing something wrong in the DrawString? Also if I draw a D and a Z the width of the D is 10px and Z is 8px, I thought using Courier it would give me fixed width?
UPDATE: I looked at the sample on MSDN and here is a screenshot. Even though the DrawString is positioned at 0,0 you can see that the letter does not appear at 0,0. The rectangle does though. There must be padding or something:
UPDATE 2: Using the following code seems to improve things although its not perfect:
StringFormat strFormat = new StringFormat(StringFormat.GenericTypographic);
Pencil.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
Pencil.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0), strFormat);
It wouldn't be the default padding / line-height etc being taken into account for the "Courier New" font would it?