Scale buttons in any resolution - c#

I'm trying to write a method that scales buttons in any resolution, on full screen without remaining space between them. Button parameters come from a web service. How can I resize them to fill all screen no matter what the parameters are. Or at least to scale their actual size to my new size. My form size is good but my buttons intersect.
private void ResizeButtons()
{
pnlDynamicControls.Height = this.ClientSize.Height
- (pnlDynamicControls.Top + pnlButtons.Height);
pnlDynamicControls.Width = pnlButtons.Width;
float widthRatio =
(float)Screen.PrimaryScreen.Bounds.Width / ClientRectangle.Width;
float heightRatio =
(float)Screen.PrimaryScreen.Bounds.Height / ClientRectangle.Height;
SizeF scale = new SizeF(widthRatio,heightRatio);
this.Scale(scale);
//if ((widthRatio - pnlDynamicControls.Width) < (heightRatio - pnlDynamicControls.Height))
// l_zoomFactor = (float)widthRatio / pnlDynamicControls.Width;
//else
// l_zoomFactor = (float)heightRatio / pnlDynamicControls.Height;
foreach (Control c in pnlDynamicControls.Controls)
{
c.Height = Convert.ToInt16(c.Height * heightRatio);
c.Width = Convert.ToInt16(c.Width * widthRatio);
c.Margin = new Padding(1, 1, 1, 1);
//c.Size = new System.Drawing.Size(
// Convert.ToInt16(c.Width * l_zoomFactor)
// , Convert.ToInt16(c.Height * l_zoomFactor)
// );
}
}

Related

How to use AddArc() method in C#

I have this little code to use AddArc() method in a label, but when I execute the code the label disappears. I believe it is the numbers I have used, I followed instructions from the Windows documentation and it had these parameters there too.
GraphicsPath gp = new GraphicsPath();
Rectangle rec = new Rectangle(20, 20, 50, 100);
gp.AddArc(rec, 0 , 180);
label2.Region = new Region(gp);
label2.Invalidate();
I used another code to make the correct way or curve in a text
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var center = new Point(Width / 2, Height / 2);
var radius = Math.Min(Width, Height) / 3;
var text = "Hello";//txtUp.Text;
var font = new Font(FontFamily.GenericSansSerif, 24, FontStyle.Bold);
for (var i = 0; i < text.Length; ++i)
{
var c = new String(text[i], 1);
var size = e.Graphics.MeasureString(c, font);
var charRadius = radius + size.Height;
var angle = (((float)i / text.Length) - 2);
var x = (int)(center.X + Math.Cos(angle) * charRadius);
var y = (int)(center.Y + Math.Sin(angle) * charRadius);
e.Graphics.TranslateTransform(x, y);
e.Graphics.RotateTransform((float)(90 + 360 * angle / (2 * Math.PI)));
e.Graphics.DrawString(c, font, Brushes.Red, 0, 0);
e.Graphics.ResetTransform();
e.Graphics.DrawArc(new Pen(Brushes.Transparent, 2.0f), center.X - radius, center.Y - radius, radius * 2, radius * 2, 0, 360);
}
}
but it wont show in front of a panel is it possible.
This is what it looks like:
Is it possible to move that text in front of the green circle?

Possibility to create live preview of WinForms form/control c#

I'm looking for possibility to create a live preview of WinForms Form/Control.
My application got two windows - one, where someone can draw on Image (which is in PictureBox), and second window, where someone can see what was been drawn on 1st window. At this moment, I tried to put the same PictureBox with image on second window, and draw the same lines on it like in window 1. Unfortunately preview like this is not live preview, because image on window 2 is refreshed when someone stop drawing on window 1. Below I'm sending a code, which is used to draw on Image.
public void AddNewPoint(int X, int Y)
{
if (_firstPointInStroke)
{
_firstpoint = _mainCustomPictureBox.PointToClient(new System.Drawing.Point(X, Y));
_firstPointInStroke = false;
}
_secondpoint = _mainCustomPictureBox.PointToClient(new System.Drawing.Point(X, Y));
var g = Graphics.FromImage(_mainCustomPictureBox.Image);
var wfactor = (double)_mainCustomPictureBox.Image.Width / _mainCustomPictureBox.Width;
var hfactor = (double)_mainCustomPictureBox.Image.Height / _mainCustomPictureBox.Height;
var resizeFactor = Math.Max(wfactor, hfactor);
System.Windows.Shapes.Line currentLine;
if (hfactor > wfactor)
{
_firstpoint.X = (float)((_firstpoint.X - ((_mainCustomPictureBox.Width - ((double)_mainCustomPictureBox.Image.Width / resizeFactor)) / 2)) * resizeFactor);
_firstpoint.Y = (float)(_firstpoint.Y * resizeFactor);
_secondpoint.X = (float)((_secondpoint.X - ((_mainCustomPictureBox.Width - ((double)_mainCustomPictureBox.Image.Width / resizeFactor)) / 2)) * resizeFactor);
_secondpoint.Y = (float)(_secondpoint.Y * resizeFactor);
}
else
{
_firstpoint.X = (float)(_firstpoint.X * resizeFactor);
_firstpoint.Y = (float)((_firstpoint.Y - ((_mainCustomPictureBox.Height - ((double)_mainCustomPictureBox.Image.Height / resizeFactor)) / 2)) * resizeFactor);
_secondpoint.X = (float)(_secondpoint.X * resizeFactor);
_secondpoint.Y = (float)((_secondpoint.Y - ((_mainCustomPictureBox.Height - ((double)_mainCustomPictureBox.Image.Height / resizeFactor)) / 2)) * resizeFactor);
}
currentLine = new System.Windows.Shapes.Line { X1 = _firstpoint.X, X2 = _secondpoint.X, Y1 = _firstpoint.Y, Y2 = _secondpoint.Y };
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawLine(_pen, (float)currentLine.X1, (float)currentLine.Y1, (float)currentLine.X2, (float)currentLine.Y2);
g.Dispose();
_mainCustomPictureBox.Invalidate();
if (_previewCustomPictureBox != null && _previewCustomPictureBox.Image != null)
{
var gg = Graphics.FromImage(_previewCustomPictureBox.Image);
gg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gg.DrawLine(_pen, (float)currentLine.X1, (float)currentLine.Y1, (float)currentLine.X2, (float)currentLine.Y2);
gg.Dispose();
_previewCustomPictureBox.Invalidate();
}
_firstpoint = _mainCustomPictureBox.PointToClient(new System.Drawing.Point(X, Y));
}
Have you any idea, how to force UI of second window to refresh after every point?
Hawex

actual dimensions of background image with "zoom" layout

With "Zoom" layout background image actual width and height do not always match the width and height of the containing control, as opposed to "Stretch" layout. I am wondering if there is a property or something in winforms to retrieve current image rendered dimensions without doing any math?
This returns the Rectangle pixels from a PictureBox for any of its SizeModes.
But yes, it does take some math for Zoom mode.
It can be adapted easily to the corresponding BackgroudImageLayout values:
Rectangle ImageArea(PictureBox pbox)
{
Size si = pbox.Image.Size;
Size sp = pbox.ClientSize;
if (pbox.SizeMode == PictureBoxSizeMode.StretchImage) return pbox.ClientRectangle;
if (pbox.SizeMode == PictureBoxSizeMode.Normal ||
pbox.SizeMode == PictureBoxSizeMode.AutoSize) return new Rectangle(Point.Empty, si);
if (pbox.SizeMode == PictureBoxSizeMode.CenterImage)
return new Rectangle(new Point( (sp.Width - si.Width) / 2,
(sp.Height - si.Height) / 2), si);
// PictureBoxSizeMode.Zoom
float ri = 1f * si.Width / si.Height;
float rp = 1f * sp.Width / sp.Height;
if (rp > ri)
{
int width = si.Width * sp.Height / si.Height;
int left = (sp.Width - width) / 2;
return new Rectangle(left, 0, width, sp.Height);
}
else
{
int height = si.Height * sp.Width / si.Width;
int top = (sp.Height - height) / 2;
return new Rectangle(0, top, sp.Width, height);
}
}

iTextSharp - Creating header/margins results in inconsistent page coordinates

Why does the following code affect a page's ability to find its top, bottom, right and left?
Before applying it, reader.GetCropBox(i).GetLeft(0) and reader.GetPageSize(i).GetLeft(0) return the far left point of every page in an assorted set. After applying it, GetLeft(0) is the far left on some pages and on others the left most point AFTER the margin ends.
I'm trying to create a header on any given set of preexisting pages (ie, create white space and then put text in it)
using (Stream stream = new FileStream(outputPdfPath2, System.IO.FileMode.Create))
{
using (PdfReader reader = new PdfReader(outputPdfPath))
{
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
int n = reader.NumberOfPages;
for (int i = 1; i <= n; i++)
{
//iTextSharp.text.Rectangle size = reader.GetPageSize(i);
iTextSharp.text.Rectangle size = reader.GetCropBox(i);
//////////
// Create Margin
float marginTop = 160;
float marginBottom = 160;
float marginLeft = 160;
float marginRight = 160;
float width = size.Width + marginLeft + marginRight; // 8.5f * 72;
float height = size.Height + marginTop + marginBottom; // 11f * 72;
float tolerance = 1f;
iTextSharp.text.Rectangle cropBox = reader.GetCropBox(i);
float widthToAdd = width - cropBox.Width;
float heightToAdd = height - cropBox.Height;
if (Math.Abs(widthToAdd) > tolerance || Math.Abs(heightToAdd) > tolerance)
{
float[] newBoxValues = new float[] {
cropBox.Left - marginLeft, // widthToAdd / 2,
cropBox.Bottom - marginBottom,// heightToAdd / 2,
cropBox.Right + marginRight, // widthToAdd / 2,
cropBox.Top + marginTop // heightToAdd / 2
};
PdfArray newBox = new PdfArray(newBoxValues);
PdfDictionary pDict = reader.GetPageN(i);
pDict.Put(PdfName.CROPBOX, newBox);
pDict.Put(PdfName.MEDIABOX, newBox);
}
//////////
}
}
}
}
The original code is borrowed from the answer given here: How to resize existing pdf page size

CreateGraphics(): Graphics is shown only on re-size

Instantiating the form.
public TwoDPlot()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US", true);
InitializeComponent();
DrawCircle();
}
Method to draw the circle.
private void DrawCircle()
{
var radius = 0.5 * ClientRectangle.Width;
var height = ClientRectangle.Height - 0.1 * ClientRectangle.Height;
var width = ClientRectangle.Width - 0.1 * ClientRectangle.Width;
var scaledRadius = width > height ? radius * (height / radius) : radius * (width / radius);
var xlocation = ClientRectangle.Width / 2.0 - scaledRadius * 0.5;
var ylocation = ClientRectangle.Height / 2.0 - scaledRadius * 0.5;
m_Graphics = CreateGraphics();
m_Graphics?.Clear(DefaultBackColor);
m_Graphics?.DrawEllipse(new Pen(Color.Red), new Rectangle((int)xlocation, (int)ylocation, (int)scaledRadius, (int)scaledRadius));
m_Graphics.Dispose();
}
On instance, it shows empty form and upon re-sizing it shows the circle. I expect to show during the first instance.
This is the direct correction:
private void TwoDPlot_Paint(object sender, PaintEventArgs e)
{
DrawCircle(e.Graphics);
}
private void DrawCircle(Graphics m_Graphics)
{
var radius = 0.5 * ClientRectangle.Width;
var height = ClientRectangle.Height - 0.1 * ClientRectangle.Height;
var width = ClientRectangle.Width - 0.1 * ClientRectangle.Width;
var scaledRadius = width > height ? radius * (height / radius) : radius * (width / radius);
var xlocation = ClientRectangle.Width / 2.0 - scaledRadius * 0.5;
var ylocation = ClientRectangle.Height / 2.0 - scaledRadius * 0.5;
m_Graphics.Clear(DefaultBackColor);
m_Graphics.DrawEllipse(new Pen(Color.Red), new Rectangle((int)xlocation, (int)ylocation, (int)scaledRadius, (int)scaledRadius));
}
Note that to be more flexible you will want to move the variables maybe to class level variables or to parameters to the DrawCircle function..
When you have done that and changed the variables values you can trigger the Paint event by calling TwoDPlot.Invalidate().
The system will also call it whenever it needs to, e.g. upon many resize, maximize and other events..

Categories

Resources