I have a windows forms application with a rectangular panel in the centre. This panel has a background image which is important for Picture boxes (with background images) which are then carefully positioned over the top of the panel. I have set the panel to Anchor Top, Bottom, Left and Right with Background image layout of Zoom. This allows the panel image to be resized when the window is resized. Great!
The problem I'm having is I need the picture boxes to stay in the same position relative to the panel background image behind it. Currently when the forms window is resized the images on top move out of position relative to the panel behind it which is resizing correctly. They are moving as if they have a Right, Bottom anchor but their anchor is set to None.
In other words, if I've positioned an image 30% of the way across the panel, I need it to be 30% across the panel even when the panel has resized.
The image below shows exactly what I am after:
http://i261.photobucket.com/albums/ii61/scottj15_2008/PanelResize_zpsfea30619.png
I have tried several Anchor and Dock Settings but not having much luck. Can anyone shine some light on this please?
Many Thanks
Actual Code for Solution (Thanks to BillWoodruff):
This solution is based upon storing the ratio for each Picturebox relative to the panel and then using that ratio within the Form_SizeChanged Method to Re-Size & Re-Poistion each PictureBox.
IMPORTANT: This Solution is based upon the panel already automatically resizing itself through use of all 4 Anchors.
First we need Dictionaries to hold position and size ratios for each picture box:
private Dictionary<Control, double> XRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> YRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> XSizeRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> YSizeRatio = new Dictionary<Control, double>();
In the Load event we need to store the ratio for each picturebox:
foreach (Control thisControl in panel.Controls)
{
if (thisControl is PictureBox)
{
XRatio.Add(theControl, Convert.ToDouble(thisControl.Left) / panel.Width);
YRatio.Add(theControl, Convert.ToDouble(thisControl.Top) / panel.Height);
XSizeRatio.Add(theControl, Convert.ToDouble(thisControl.Width) / panel.Width);
YSizeRatio.Add(theControl, Convert.ToDouble(thisControl.Height) / panel.Height);
}
}
We then need to use this ratio to Re-Size/Re-Position each PictureBox whenever the form window is resized:
private void Form_SizeChanged(object sender, EventArgs e)
{
foreach (Control thisControl in panel.Controls)
{
if (thisControl is PictureBox)
{
double localXRatio = 0;
double localYRatio = 0;
localXRatio = XRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
localYRatio = YRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
newX = Convert.ToInt32(panel.Width * localXRatio);
newY = Convert.ToInt32(panel.Height * localYRatio);
thisControl.Location = new Point(newX, newY);
double localXSizeRatio = 0;
double localYSizeRatio = 0;
localXSizeRatio = XSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
localYSizeRatio = YSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
newWidth = Convert.ToInt32(panel.Width * localXSizeRatio);
newHeight = Convert.ToInt32(panel.Height * localYSizeRatio);
thisControl.Width = newWidth;
thisControl.Height = newHeight;
}
}
}