Centered and scrolled PictureBox in WinForms - c#

I'm developing a WinForms application and can't figure out how to resolve an issue.
I need to show an image in a Form. Because the image can be arbitrarily large, I need scrollbars on the picturebox containing the image so the user can see it entirely.
Googling around I found out the best way to achieve this is to add the PictureBox as a Child Control of a Panel, and making the Panel autosizable and autoscrollable.
I did that programatically since using the designer I was unable to insert the picturebox as a child control of the panel.
The problem I'm now facing is that I can't seem to be able to center and scroll the picturebox at the same time.
If I put the anchor of the picturebox to top,left,bottom,right, the scrollbars are not shown and the image displayed is strange, if I put back the anchor to only top-left, the image is not centered.
Is there any way to do both at the same time?
Here's the code for my Panel and Picturebox:
this.panelCapturedImage = new System.Windows.Forms.Panel();
this.panelCapturedImage.SuspendLayout();
this.panelCapturedImage.AutoScroll = true;
this.panelCapturedImage.AutoSize = true;
this.panelCapturedImage.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.panelCapturedImage.Controls.Add(this.pictureBoxCapturedImage);
this.panelCapturedImage.Location = new System.Drawing.Point(0, 49);
this.panelCapturedImage.Name = "panelCapturedImage";
this.panelCapturedImage.Size = new System.Drawing.Size(3, 3);
this.panelCapturedImage.TabIndex = 4;
this.pictureBoxCapturedImage.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pictureBoxCapturedImage.Location = new System.Drawing.Point(0, 0);
this.pictureBoxCapturedImage.Name = "pictureBoxCapturedImage";
this.pictureBoxCapturedImage.Size = new System.Drawing.Size(0, 0);
this.pictureBoxCapturedImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBoxCapturedImage.TabIndex = 0;
this.pictureBoxCapturedImage.TabStop = false;
this.panelCapturedImage.Controls.Add(this.pictureBoxCapturedImage);
And here's where I set the image:
public Image CapturedImage
{
set
{
pictureBoxCapturedImage.Image = value;
pictureBoxCapturedImage.Size = value.Size;
}
}

For the PictureBox, set SizeMode = AutoSize, Anchor it Top, Left, and set its Location to 0, 0.
Set Panel.AutSize to False and Panel.AutoScroll to True.
When you set the PictureBox.Image property, it will auto-size to the size of the image. You can then use that size to set the panel's AutoScrollPosition property:
public Image CapturedImage
{
set
{
pictureBoxCapturedImage.Image = value;
panelCapturedImage.AutoScrollPosition =
new Point {
X = (pictureBoxCapturedImage.Width - panelCapturedImage.Width) / 2,
Y = (pictureBoxCapturedImage.Height - panelCapturedImage.Height) / 2
};
}
}
If the image is smaller then then panel's size, it will remain in the upper left corner. If you want it centered within the panel, you'll have to add logic to set its Location appropriately.

Based on earlier answers I was able to create this full example:
private void testShowPictureBox()
{
/* format form */
Form frmShowPic = new Form();
frmShowPic.Width = 234;
frmShowPic.Height = 332;
frmShowPic.MinimizeBox = false;
frmShowPic.MaximizeBox = false;
frmShowPic.ShowIcon = false;
frmShowPic.StartPosition = FormStartPosition.CenterScreen;
frmShowPic.Text = "Show Picture";
/* add panel */
Panel panPic = new Panel();
panPic.AutoSize = false;
panPic.AutoScroll = true;
panPic.Dock = DockStyle.Fill;
/* add picture box */
PictureBox pbPic = new PictureBox();
pbPic.SizeMode = PictureBoxSizeMode.AutoSize;
pbPic.Location = new Point(0, 0);
panPic.Controls.Add(pbPic);
frmShowPic.Controls.Add(panPic);
/* define image */
pbPic.ImageLocation = #"c:\temp\pic.png";
frmShowPic.ShowDialog();
}

The picturebox has to be set to autosize. anchored at the center (or a border).
You could manage all of this in the designer, don't undertand your problem with that.
The panel has to be set to autoscroll to true.

Related

in c# winform, How to keep a control always in the center bottom of a form when form's size changed?

in c# winform, How to keep a control always in the center bottom of a form when form's size changed?
if I use DockStyle.Bottom, I can't set its width.
I tried it out. The following is the code, but I don't know why? It's mainly because I don't understand why the Left value will change when the Anchor. Bottom is set?
public void Run()
{
Form form = new Form();
form.Width = 600;
form.Height = 600;
Button btnOK = new Button();
btnOK.Text = "OK";
btnOK.Left = form.ClientSize.Width / 2 - btnOK.Width;
btnOK.Top = 0;
btnOK.Anchor = AnchorStyles.Bottom;
Button btnCancel = new Button();
btnCancel.Text = "Cancel";
btnCancel.Left = form.ClientSize.Width / 2;
btnCancel.Top = 0;
btnCancel.Anchor = AnchorStyles.Bottom;
Panel panel = new Panel();
panel.Height = btnOK.Height;
panel.Width = form.ClientSize.Width;
panel.Dock = DockStyle.Bottom;
panel.Controls.Add(btnOK);
panel.Controls.Add(btnCancel);
form.Controls.Add(panel);
form.Show();
}
Use a TableLayoutPanel. You can Dock it to the Bottom or Anchor it to the Bottom, Left and Right. You would have one row then have a column with an absolute width for each control and one extra column on the left and another on the right with 50% width. Those two extra columns will take up half the empty space each, thus keeping the others in the middle.

I am trying to add a PictureBox dynamically to a TableLayoutPanel but it's not filling the selected cell

I use this part of code to add the picture but it's half the cell...and still it's not working.
PictureBox pB = new PictureBox {
Size = MaximumSize,
Dock = DockStyle.Fill,
BackgroundImageLayout = ImageLayout.Stretch
};
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK) {
string path = ofd.FileName;
pB.Image = new Bitmap(path);
}
tableLayoutPanel1.Controls.Add(pB, x-1, y-1);
Control control = tableLayoutPanel1.GetControlFromPosition(x - 1, y - 1);
control.Dock = DockStyle.Fill;
control.BackgroundImageLayout = ImageLayout.Stretch;
You are confusing the two images a PictureBox can have:
The Image is the main one with all sorts of capabilties
The BackgroundImage is below it and can be use for just that: A background.
You want to set the layout for the Image; it is called SizeMode
PictureBox pB = new PictureBox
{
Size = MaximumSize,
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
Not sure where and how you set x and y but you should see the full image now, albeit more or less stretched.
And you don't need to set the SizeMode or Docking again at the end..

Make Panel scrollable

I am working on a simple Windows Forms application which consists of a Panel where I draw graphics with Graphic. Let's say, my panel is now of size 300x300 but the content inside is 500x500. Obviously, I need to add scrollbars to the Panel.
My code so far:
public CircuitControl()
{
// Initialize empty list of circuit objects
CircuitObjects = new List<CircuitObject>();
drawingAreaPanel.AutoScroll = true;
drawingAreaPanel.VerticalScroll.Enabled = true;
drawingAreaPanel.VerticalScroll.Visible = true;
drawingAreaPanel.HorizontalScroll.Enabled = true;
drawingAreaPanel.MaximumSize = new Size(300, 300);
drawingAreaPanel.Size = new Size(600, 600);
}
But none of these codes create actually a scroll bar. My question is: Where and how do I set the size of the Panel where I actually drew? I think this is the part which is missing. Thanks.
The scrollbars won't show up until there's actually something in the Panel that you can't see all of.
Try placing a larger control, such as a PictureBox, inside the Panel, and setting the PictureBox's initial size as larger than the Panel.
Just add:
drawingAreaPanel.AutoScroll = true;
And it will be done automatically.
€dit: Don't forget to set the anchors in order to get the scrollbars.
A clean and simple approach is to set AutoScrollMinSize. This shows the scrollbars (or just one if you leave the other value at 0).
Now drawing through the graphics object will not be scrolled automatically.
This can be easily achieved with a transformation matrix, which is set before painting and translates the drawing by the scroll offset.
A pretty example: (this flickers of course without further optimizations)
private void button1_Click(object sender, EventArgs e)
{
using(Form frm = new Form())
{
Panel pnl = new Panel();
pnl.Paint += delegate (Object snd, PaintEventArgs e2) {
Matrix mtx = new Matrix();
mtx.Translate(pnl.AutoScrollPosition.X, pnl.AutoScrollPosition.Y);
e2.Graphics.Transform = mtx;
e2.Graphics.Clear(Color.Black);
for(int i=0; i <= 125; i++)
for(int j=0; j <= 125; j++)
using(Brush b = new SolidBrush(Color.FromArgb(255, 255-i*2, j*2, (i*j) % 255)))
e2.Graphics.FillRectangle(b, new Rectangle(5+j*20, 5+i*20, 20, 20));
};
pnl.AutoScrollMinSize = new Size(126*20+10, 126*20+10);
pnl.Dock = DockStyle.Fill;
frm.Controls.Add(pnl);
frm.Padding = new Padding(25);
frm.ShowDialog(this);
}
}

Forcing the inner part of a form to stay in the same position while changing border style

I have a winform that starts out with a sizable border around it. On the form is a button which, when pressed, changes the form to border style none.
The problem is that then the inner part of the form moves up and to the left slightly. I want to make it that, no matter what border is used, the "inner" part of the form will always stay in the same spot (note: but I do still want the form to be moved around when it has a movable border selected)
Thanks.
The Borderless form moves up and slightly left because thats the location that the form currently has,you need to count for the border.To achieve the result you are after you need to reassign the location property and to do that you need to account for the client size and the whole size(with border),the code i think is simple and it will be self-explanatory i believe:
private void button1_Click(object sender, EventArgs e)
{
var X = (this.Size.Width - this.ClientRectangle.Width) / 2;
var Y = (this.Size.Height - this.ClientRectangle.Height) - X;
Point p = new Point(Location.X + X, Location.Y + Y);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Location = p;
}
Another option is to set the padding on the parent that contains the panel with the border. E.g.
public class Form10 : Form {
Button btn = new Button { Text = "Button", Location = new Point(100, 100) };
Panel border = new Panel { Dock = DockStyle.Fill, BorderStyle = BorderStyle.Fixed3D };
public Form10() {
Controls.Add(border);
border.Controls.Add(btn);
btn.Click += delegate {
if (border.BorderStyle == BorderStyle.Fixed3D) {
border.BorderStyle = BorderStyle.None;
border.Parent.Padding = new Padding(2);
}
else {
border.BorderStyle = BorderStyle.Fixed3D;
border.Parent.Padding = new Padding(0);
}
};
}
}

WebBrowser control: how to maximize it

I use WebBrowser in some DLL to make screenshots.
The main problem that it is not maximized sometimes and I guess it takes settigns of the Internet Explorer.
So my question is how to maximize WebBrowser control via C#?
Thank you!
Rectangle r = new Rectangle();
r.X = cropToRectangle.X;
r.Y = cropToRectangle.Y;
r.Width = cropToRectangle.Width;
r.Height = cropToRectangle.Height;
Point p = new Point();
p.X = scrollTo.X;
p.Y = scrollTo.Y;
var sb = Math.Max(SystemInformation.VerticalScrollBarWidth, SystemInformation.HorizontalScrollBarHeight);
var size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
using (var form =
new FocuslessForm
{
Width = size.Width + sb,
Height = size.Height + sb,
Padding = new Padding(0),
Margin = new Padding(0),
FormBorderStyle = FormBorderStyle.None,
Opacity = 0,
TabStop = false,
ShowInTaskbar = false
})
{
var webBrowser1 = new WebBrowser
{
Padding = new Padding(0),
Margin = new Padding(0),
Dock = DockStyle.Fill,
Url = url,
TabStop = false
};
form.Controls.Add(webBrowser1);
var finished = false;
webBrowser1.DocumentCompleted += delegate
{
webBrowser1.Document.Window.ScrollTo(p);
finished = true;
};
form.Show();
while (!finished)
{
Application.DoEvents();
}
image = CaptureBrowserScreenshot(webBrowser1, r);
form.Close();
}
Well, the WebBrowser is a control that is embedded into your own program's window; it doesn't launch IE as a separate process (though it does hook into IE for the renderer and other critical code). So, the control's location and size is dependent on where you embed it.
I see you are fill-docking the control to the form. This is a good first step. Now, you must make sure the WebBrowser control is being added to the Controls hierarchy of the Form (so it'll show up), and then you must maximize that Form. The way to do this is to set the WindowState property of the Form to WindowState.Maximized.
I implemented Form resize event, when form is maximize, i set web browser size to form size.
It worked well in my app, I share for whom concern.
private void Form1_Resize(object sender, EventArgs e)
{
webBrowser1.Size = this.Size;
}

Categories

Resources