How to determine if control is outside of Form? - c#

I am trying to determine if a dynamically added control is outside of the form.
At first, I thought it might be possible to calculate it by getting the height of the form, and location of the dynamically added control.
But I noticed that the Control.Location and Form.Height have "nothing" in common.
I don't think I really understand what the correlation is between Height and Location.
For example:
I thought that if your form has a height of 500, and I put the control at the bottom of the form, it should give the Location: X, 500 (X is width, not relevant here). But this is not correct, it shows me for example: X, 465. Am I missing something?
So I need to be able to recognize if the control is outside of the form, even if it's just one pixel.
I've found several similar questions here on SO, yet this does not really give me the answer that I need, unfortunately.
So, is there any way to do this? Is it possible to calculate it?

The Height of the form also includes the height of the title bar and borders.
You can use the ClientSize of the form:
From the documentation on MSDN:
The size of the client area of the form is the size of the form excluding the borders and the title bar. The client area of a form is the area within a form where controls can be placed. You can use this property to get the proper dimensions when performing graphics operations or when sizing and positioning controls on the form. To get the size of the entire form, use the Size property or use the individual properties Height and Width.
The position of the control is relative to its container, so (0,0) is the left upper corner inside the form.

I know this is an older thread, but you can try using this method:
public static bool IsOutofBounds(Form form, Control control)
{
int controlEnd_X = control.Location.X + control.ClientSize.Width;
int controlEnd_Y = control.Location.Y + control.ClientSize.Height;
if (form.ClientSize.Width < controlEnd_X || form.ClientSize.Height < controlEnd_Y)
{
return true;
}
else
{
return false;
}
}
It works for checking whether a control is out of bounds of its parent form.

You could use this code to check if controls is inside form:
var Inside = frm.ClientRectange.Intersect(ctrl.Bounds) == ctrl.Bounds;

the top left corner of a form is (0,0) lower right corner is (formHeight, fromWidth).
to check this place two text boxes on a form and write this code in the mouse move event to see how x and y change.
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
textBox1.Text = e.X.ToString();
textBox2.Text = e.Y.ToString();
}
Note that there is an difference between the number returned from the edge of the form and the size chosen by you. In my 500*500 form it is actually 460*483. the difference is always the same for any border style and any resolution.
To place a control on your form use the location structure in the form or use the top and left properties for the control; top = x, left = y.
Remember your offset from the actual height and width you measured and the dimension of the control.
To add a button with the following dimensions 80*30 in the bottom right corner I would right something like this:
button1.Location = new System.Drawing.Point(402, 430);
bottom left corner:
button1.Location = new System.Drawing.Point(0, 430);

Related

How to place a label or a button exactly in the middle of the Form?

I can't find tools or properties to place a label or a button exactly in the middle of the Form. For example, on the X axis. VS 2015.
Design time :
In my VisualStudio2010 I have these 2 buttons to center horizontally and vertically:
Its located in the toolbar "Layout". If it isn't, you can add them by clicking the small button to the right. It is also in the Format menu.
To keep centered at Runtime: Turn off all anchoring.
Note:This will keep the control at its relative position as long as it doesn't change it Size. If it does, like autosize Labels are prone to, you will have to code the Resize event. Examples are here
For controls that may change in size, you need to catch the Resize event.
In my case I have a Panel, representing a page, inside another Panel which is the workspace. The workspace is set to autoscroll. In this scenario, it's important that the control is only centered when smaller than the container.
Whenever the form changes size or when I change the content, I call this function:
private void resetPagePos()
{
int wWS = pnlWorkspace.Width;
int hWS = pnlWorkspace.Height;
int wPage = pnlPage.Width;
int hPage = pnlPage.Height;
pnlPage.Location = new Point(Math.Max(0, (wWS - wPage) / 2), pnlPage.Top = Math.Max(0, (hWS - hPage) / 2));
}
The use of Math.Max(0, ...) makes sure that if the item doesn't fit, and the scrollbars are activates, then our page scrolls correctly. If the Left or Top are set to a negative number, you would get unwanted side-effects.

SplitContainer Panel Resize Issue

The General Problem
The application is C# WinForms .Net 4.0.
I have a SplitContainer that takes up most of the form, it is set to Anchor in all directions so it re-sizes along with the form. The left panel (Panel1) has a simple menu, no problems here. The right panel (Panel2) is more complex and contains a number of nested tab controls (with lots of controls) - it is painfully complex, but it's not changing.
The problem is that re-sizing the form doesn't work so well. In fact, if you resize by dragging the edges slowly then it works ok, but drag quickly or use the "restore" button (top-right of form) then the issue occurs.
My Control Hierarchy
The following is a simple example of my control hierarchy, its definitely a cut down version but does highlight the nested tab control which may help with replication:
Form
Split Container (anchor: top, left, bottom, right)
SC Panel1 (min width: 300)
TreeViewControl (forget what it is called)
SC Panel2
Panel (anchor: top, left, bottom, right)
Tab Control (anchor: top, left, bottom, right)
Tab Control w/ lots of pages that overflow screen and require the navigation buttons to show in top right corner (anchor: top, left, bottom, right)
Debug Details
After some debugging it appears that it is in fact Panel2 (a child of the split container) that doesn't resize properly, and the actual SplitContainer itself resizes fine.
Here are the debug values that show this...
Full width form, before resize:
splitContainerMain.Width: 1479
splitContainerMain.Panel2.Width: 1206
panelCenter.Width: 1203
tabControlMain.Width: 1215
All as expected, splitContainerMain.Panel2.Width is smaller than splitContainerMain.Width.
After resize where the issue occurs:
splitContainerMain.Width: 815
splitContainerMain.Panel2.Width: 1206
panelCenter.Width: 1203
tabControlMain.Width: 1215
As can be seen, the splitContainerMain.Width has resized as desired, but the splitContainerMain.Panel2.Width and subsequently its children have not.
NOTE: Please remember, the width updates correctly if I manually resize the form slowly - this is not a problem with me not correctly setting any anchors.
My Efforts So Far
What I have tried to do is use various Form resize events and try to set the widths manually, but to no avail. I think what I would like to try is to set the Panel2.Width value from within an event of some sort.
What I Am Looking For
Is there anyway to force splitContainerMain.Panel2.Width to resize correctly when the splitContainerMain size changes?
Alternatively, how can I calculate what the Panel2.Width should be? And how can I set that value from the Form.Resize event? (or another event?)
Though the question is about 6 years old, I opted to answer this because I was in the same situation as the opening post. Unfortunately, the orientation was not specified. So, my answer would address the ones with Horizontal orientation.
Please translate to C# as this code is in VB.
Private Sub splitContainerMain_Resize(sender As Object, e As EventArgs) Handles splitContainerMain.Resize
'/* This is a work around about panels being left out when SplitContainer is resized */
Dim pnl1Height As Single = splitContainerMain.SplitterDistance '/* Get upper panel height */
Dim pnl2Height As Single = splitContainerMain.Height - splitContainerMain.SplitterDistance '/* Get lower panel height */
splitContainerMain.Panel1.SetBounds(0, 0, splitContainerMain.Width, pnl1Height) '/* Set Upper panel bounds */
'/* Set lower panel bounds, with a top of upper panel height plus splitter width */
splitContainerMain.Panel2.SetBounds(0, pnl1Height + splitContainerMain.SplitterWidth, splitContainerMain.Width, pnl2Height)
End Sub
From what I see u should set anchor to none for controls that are creating problem including splitcontainer pannels.
Also I would suggest to use dock fill property to best use the splitcontainers.
If need further help please provide designer file so can have a better look.
So on each Change event you are creating a new thread, that thread will then wait 100 ms and then do the recize??? thats stupid. You can have a thread created at the constructor, then calling Start() on your thread which could have the following:
private void resizeMe()
{
this.BeginInvoke((Action)() => {
splitContainer.Height = tableBorder.Height;
splitContainer.Width = tableBorder.Width;
}
}
Exactly the same problem, below code worked for me:
Surround splitContainer in a panel "tableBorder"
On tableBorder
Dock = DockStyle.Fill;
On split Container, (no anchoring)
Dock = DockStyle.None;
On tableBorder SizeChanged event
private void tableBorder_SizeChanged(object sender, EventArgs e)
{
new Thread(() => { resizeMe(); }).Start();
}
private void resizeMe()
{
Thread.Sleep(100);
this.BeginInvoke((Action)(() => {
doIt();
}));
}
private void doIt()
{
splitContainer.Height = tableBorder.Height;
splitContainer.Width = tableBorder.Width;
}
There is a small lag, but works

PictureBox size coordinates relation

I'm asking a question here cause I'm not sure how to search it in google, I don't know the word how to call this.
What I mean is a "zero point" which basically located at upper-left corner of the element, pictureBox for an example. So when I set new width and height properties for my pictureBox it works fine but it's relative to top left corner.
What I mean is you've got pictureBox, let's say 100 x 100 and you desire decrease it to 50 x 100, so you will get "empty space" under your picture box, not upper. PictureBox counts it's properties from this one top left corner zero point.
And what I need is to change this point to the another corner.
So when I change my height it count up, not down. Help me please.
I really hope you can understand me.
Wow, thank you guys for your advices! I've tested anchor property and Top += 50; now, doesn't solve my problem. Let me try to describe it another way. You have an image (100px) with grass 50px at bottom and sky 50px at the top. So you have picturebox with height 100. If you set pictureBox.height = 50; you will see only sky. But I need to leave only grass. The main problem I see here is because this zero point at top left corner.
Here is an example:
Button1 click event:
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Height = 150;
}
The result which you will get after you press the button:
But I need another result:
As I understand it happens because height property counts from the top left corner. So if I change it to bottom left or right corner it will works the way I need. Help me please to change this point...
MSDN reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox.sizemode(v=vs.71).aspx
Valid values for this property are taken from the PictureBoxSizeMode enumeration. By default, in PictureBoxSizeMode.Normal mode, the Image is placed in the upper left corner of the PictureBox, and any part of the image too big for the PictureBox is clipped. Using the PictureBoxSizeMode.StretchImage value causes the image to stretch to fit the PictureBox.
Unless you are using a container which handles control layout automatically, you will have to move it yourself. I assume you are resizing the control in code with a line like:
myPictureBox.Height = 50;
You will have to also move the control's location down by the same amount:
myPictureBox.Top += 50;
Generalizing, something like this ought to do the trick for resizing height:
void ResizeHeightFromBottom(this Control c, int newHeight)
{
var oldBottom = c.Bottom;
c.Height = newHeight;
c.Top = oldBottom - newHeight;
}
I will leave resizing the width and both simultaneously as an exercise for the reader, as well as specifying an arbitrary reference point.

How is it possible to centre a form in C#

How can you centre a form in C#, so it appears in the middle of the screen
If you're talking about where it starts, use Form.StartPosition:
form.StartPosition = FormStartPosition.CenterScreen;
If you want to do it at an arbitrary time, you'll need to work out the size of the screen, the size of the form, and calculate it yourself before setting the Location property accordingly.
Use the StartPosition property of the form, change it to CenterScreen.
In Winforms, there is a property of a Form control called StartPosition; it's an enumeration, which includes the position "CenterScreen". Use this, and your window will appear, when first created, in the middle of the monitor on which the mouse is currently located.
You can set the StartPosition property in the designer
Click your form and press F4 to show the Properties tab, then scroll down to the StartPosition property and change the value to CenterScreen.
If you want it to be centered at startup, set your form's StartPosition ( http://msdn.microsoft.com/en-us/library/system.windows.forms.form.startposition.aspx ) to CenterScreen.
If you want it to be centered some other time, you have to use the SystemInformation.WorkingArea class ( http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.workingarea.aspx ) and perform arithmetic on that like so:
X = (Screen Width - Form Width) / 2
Y = (Screen Height - Form Height) / 2
And then consider what should happen if your form was too big. Setting either or both coordinates to a negative number is poor form, so don't forget that case.

WM6 .Net Form Effects C#

I would like to know if it's possible to create nice form effects on the compact framework.
My plan is that when a user selects an image on the main form this is opened in a new form, this currently works. What I now want to do is make the form that contains the fullsize picture to load off the edge (left or right) of the screen at around 4 pixels high then slide into view. Once the form is fully on the screen then expand the height until it hits the max for the screen.
On close i would like to reduce the height back down to the 4 pixels high and the slide off the edge again before disposing the form.
I've tried the code below when instantiating the form and the dp.Top property was always 0 regardless of dp.Width == 240
DisplayPicture dp = new DisplayPicture(ImageUrl);
dp.WindowState = FormWindowState.Normal;
dp.Left = dp.Width * -1;
dp.Top = (dp.Height / 2) - 2;
dp.Height = 4;
dp.ShowDialog();
Within the DisplayPicture form i also have the following to try and move the form but as it isn't setting the Top property this code doesn't matter yet.
void t_Tick(object sender, EventArgs e)
{
if (this.Left < 0)
this.Left += 5;
if (this.Left > -1)
{
this.Left = 0;
if (this.Height < pictureBox1.ClientRectangle.Height)
{
this.Height += 4;
this.Top -= 2;
}
if ((this.Left == 0) && (this.Top == 0))
t.Enabled = false;
}
}
Any help would be greatly appreciated!
TIA
OneSHOT
To do this, start with a PictureBox control that has your image loaded. Set the Height to 4, the Width to the width of your form, and (very important) set the SizeMode of the PictureBox to StretchImage.
Next, position the PictureBox off the screen by setting Top to 0 and Left to -Width. Put a Timer control on your form with an interval of 100 (or whatever), and have its event gradually move the PictureBox to the right until its Left property is 0. Once you reach that point, have the timer event gradually increase the Height until it reaches the height of the form.
You'll probably have to deal with flicker, but this should get you started.
Update: I just read your question a little closer, and realized that you actually want to move the form itself from offscreen to full screen. This is not possible if you want the entire form (including the title bar at the top) to animate in this way, but you can sort of do this by setting the form's FormBorderStyle (or I think it's just called BorderStyle in the Compact Framework) to None. With the BorderStyle set to None, changing the Height, Width, Top and Left properties will actually have a visible effect on the form (although the form will be borderless). These properties are otherwise ignored completely in Windows Mobile, which is probably why your code didn't appear to be doing anything.
Update 2: here is my answer to a similar WM question, which may help you make your animated window look like a real window.

Categories

Resources