Click here to Skip to main content
15,881,938 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
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:
C#
//Location Ratios
private Dictionary<Control, double> XRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> YRatio = new Dictionary<Control, double>();
//Size Ratios
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:
C#
foreach (Control thisControl in panel.Controls)
{
    if (thisControl is PictureBox)
    {
        //Location Ratios
        XRatio.Add(theControl, Convert.ToDouble(thisControl.Left) / panel.Width);
        YRatio.Add(theControl, Convert.ToDouble(thisControl.Top) / panel.Height);
        //Size Ratios
        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:
C#
private void Form_SizeChanged(object sender, EventArgs e)
{
    foreach (Control thisControl in panel.Controls)
    {
        if (thisControl is PictureBox)
        {
            //*********************Re-Position the PictureBox********************
            double localXRatio = 0;
            double localYRatio = 0;
            //Grab the Location Ratios for this particular PictureBox
            localXRatio = XRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            localYRatio = YRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            //Calculate the new Location by using the ratios
            newX = Convert.ToInt32(panel.Width * localXRatio);
            newY = Convert.ToInt32(panel.Height * localYRatio);
            //Set the new Location
            thisControl.Location = new Point(newX, newY);
            //*********************Re-Size the PictureBox********************
            double localXSizeRatio = 0;
            double localYSizeRatio = 0;
            //Grab the Size Ratios for this particular PictureBox
            localXSizeRatio = XSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            localYSizeRatio = YSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            //Calculate the new sizes by using the set ratio
            newWidth = Convert.ToInt32(panel.Width * localXSizeRatio);
            newHeight = Convert.ToInt32(panel.Height * localYSizeRatio);
            //Set the new Size
            thisControl.Width = newWidth;
            thisControl.Height = newHeight;
        }
    }
}
Posted
Updated 7-Jan-14 12:35pm
v7
Comments
CHill60 6-Jan-14 16:56pm    
This is working fine for me when I try it ... you said "carefully positioned over the top of the panel" ... for the Anchor to work the picture boxes need to be inside the panel - is that your problem?
Member 10334528 6-Jan-14 17:11pm    
Hi, Thanks for your reply. Yes the picture box's's are defiantly in the panel as they all move with the panel when I move the panel in design view. The X and Y locations are also relative to the panel and not the form confirming this.
CHill60 6-Jan-14 17:14pm    
It was worth a try :-) Thanks for confirming. I'll have another go at trying to recreate your problem
CHill60 6-Jan-14 17:53pm    
Just a thought - are you docking the image with all 4 of Top, Bottom, Left and Right? And is it the picture box Image or BackgroundImage that you are using?
Member 10334528 6-Jan-14 18:09pm    
Nothing is currently Docked but the Panel does have all 4 Top, Bottom, Left, Right Anchors along with BackgroundImageLayout = Zoom so that it resizes on any window resize.

The Picture box's use a background image and have no anchor but they appear to be behaving in a way that they would if Right and Bottom Anchor were to be selected.

Here's an overview of how to achieve relative positioning and re-sizing of Controls when the Controls Form/ContainerControl changes size [^].

I've not been able to get permission, yet, to publish the entire code on CP, but, I hope to.

I suggest you read the various comments on the post, and the other responses. I also suggest you avoid trying to scale FontSize in Controls with Text: that's usually leads to a typographic mess in WinForms.
 
Share this answer
 
Comments
Member 10334528 7-Jan-14 18:33pm    
Thanks so much! I have played around for the last 2-3 hours with the stuff you provided and I have successfully got all PictureBoxes to resize and relocate with formwindow resizing.

I have accepted your solution and updated the question with the code I used to assist anyone in the future.

Many Thanks!! :)
I think you have mentioned the solution yourself,

If I understood the problme right, you need to use a ratio like you said.

use this ratio to resize those picture boxes using width, height and relocate them using left, top properties in Code
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900