I have an application that has 2 forms, a child and a parent. I want to make sure that the parent window can never be inside the child window in any way, so the code will need to check if any part of the parent window's bounding box is within the child window's bounding box. How can I accomplish this?
I tried this code: - if ((Owner.Top > this.Top) && (Owner.Top < this.Bottom + 10) && ((Owner.Left > this.Left) && (Owner.Left < this.Right + 10)))
-
{
-
Owner.Top = this.Bottom + 10;
-
}
But that only checks if the top left corner of the parent window is within the child window, not the whole thing. Is there any way to check the entire bounding box and see if there is any overlap?
As you can see with the code I'm using, if the parent is found to be within the child window, it puts it it at the bottom of the child window, plus 10 pixels. This poses a problem if the child window is moved to the bottom of the screen, which would cause the parent window to be pushed off the screen, so I'll also need to be able to check if the parent window is close to the screen border and perhaps put it above the child window instead of below.
There should also be something in place just in case the child window is expanded to the entire size of the screen, giving no room for the parent window, then it should allow the parent window to overlap the child window.
4 3956
Bounding box checking is fairly standard... Using this image...
You have containment...
IF - Bx >= Ax AND // Left > Left
- Bx + Bw <= Ax + Aw AND // Right < Right
- By >= Ay AND // Top > Top
- By + Bh <= Ay + Ah // Bottom < Bottom
You have intersection...
IF - Bx <= Ax + Aw AND // Left < Right
- Bx + Bw >= Ax AND // Right > Left
- By <= Ay + Ah AND // Top < Bottom
- By + Bh >= Ay // Bottom > Top
While this is easy enough to code, fortunately, Microsoft provides us a Rectangle class which will actually do the calculation for us in the System.Drawing namespace.
Here's a demo program... - class Program
-
{
-
static void Main(string[] args)
-
{
-
RectangleObject A = new RectangleObject("A", 5, 5, 10, 10);
-
RectangleObject B = new RectangleObject("B", 7, 7, 10, 10);
-
RectangleObject C = new RectangleObject("C", 7, 7, 5, 5);
-
RectangleObject D = new RectangleObject("D", 20, 20, 10, 10);
-
-
List<RectangleObject> rectList = new List<RectangleObject>();
-
rectList.AddRange(new RectangleObject[] { A, B, C, D });
-
-
foreach (RectangleObject r1 in rectList)
-
{
-
foreach (RectangleObject r2 in rectList)
-
{
-
if (r1 != r2)
-
{
-
if (r1.Contains(r2))
-
{
-
Console.WriteLine(r1 + " contains " + r2);
-
}
-
else
-
{
-
Console.WriteLine(r1 + " does not contain " + r2);
-
}
-
-
if (r1.IntersectsWith(r2))
-
{
-
Console.WriteLine(r1 + " intersects with " + r2);
-
}
-
else
-
{
-
Console.WriteLine(r1 + " does not intersect with " + r2);
-
}
-
}
-
}
-
}
-
}
-
-
public class RectangleObject
-
{
-
public Rectangle Rectangle { get; set; }
-
public string Name { get; set; }
-
-
public RectangleObject(string name, int x, int y, int width, int height)
-
{
-
Name = name;
-
Rectangle = new Rectangle(x, y, width, height);
-
}
-
-
public bool IntersectsWith(RectangleObject rectObj)
-
{
-
return Rectangle.IntersectsWith(rectObj.Rectangle);
-
}
-
-
public bool Contains(RectangleObject rectObj)
-
{
-
return Rectangle.Contains(rectObj.Rectangle);
-
}
-
-
public override string ToString()
-
{
-
return this.Name + ":" + string.Format("({0}, {1})-({2}, {3})", Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom);
-
}
-
}
-
}
Note: I only made the class so I could name the objects for easier reference :)
Also, and this is just as a fun suggestion, instead of putting it at a fixed position you could always place it a little more intelligently. You can get the vector between the two center points of the forms, then place the form along that vector at a position that puts the child form outside the parent form. What distance would that be? Well, imagine a circle contains each of your forms, what's the minimum radius of that circle? The longest distance from the center to the top-left or top-right corners. Then add that distance to the center distance of the other form and place it there. You can be a little more precise if you want to compare the lines that center vector intersects with (which is also more fun!) but the circle method is typically the simplest.
Aaaanyway, I digress. Hope that all helps!
Ok, so I used this code to determine whether the child form contains or intersects with the parent form: - public void moveParentBox()
-
{
-
Rectangle ownerRect = new Rectangle(Owner.Location, Owner.Size);
-
Rectangle thisRect = new Rectangle(this.Location, this.Size);
-
-
if (thisRect.Contains(ownerRect))
-
{
-
Owner.BackColor = Color.Red;
-
} else if (thisRect.IntersectsWith(ownerRect))
-
{
-
Owner.BackColor = Color.Blue;
-
}
-
else
-
{
-
Owner.BackColor = Color.FromName("Control");
-
}
-
}
And it seems to work. If I move the parent form partially within the child form, the background turns blue, if the parent form is fully within the child form, it turns red. If both return false the background color is reset. Since I don't need to detect each event by itself, only whether any part of the parent form is within the child form, I could condense it to this: - public void moveParentBox()
-
{
-
Rectangle ownerRect = new Rectangle(Owner.Location, Owner.Size);
-
Rectangle thisRect = new Rectangle(this.Location, this.Size);
-
-
if (thisRect.Contains(ownerRect) || thisRect.IntersectsWith(ownerRect))
-
{
-
Owner.BackColor = Color.Red;
-
}
-
else
-
{
-
Owner.BackColor = Color.FromName("Control");
-
}
-
}
Now, I didn't get your second part. I think I understand the concept, but I can't seem to visualize the results you're going for with it. Can you help me better understand?
Also, thanks a ton for that rectangle tip, I wouldn't have found that out myself, I would have done it the hard way.
Glad you got it working! Bounding boxes are great... I've used them a lot, love 'em ;)
For that second part, it was more a way to move your window in a way that it would be a little more natural. How much do you know about vectors and vector math?
If nothing, here's the wikipedia: http://en.wikipedia.org/wiki/Euclidean_vector
(Note: That article makes it look a lot more complicated than it really is... but hopefully you can get something from it. Damn wiki elitists, making everything confusing ><)
This is a little more complex than I want to write up here... let me do a little example program using spheres when I get some time and I'll post it so you can see what I'm getting at.
I'll get back to you :)
Ok, here we go... it's a fair bit of code and I can't guarantee the best coding practices since I just threw it together, but it should be sufficient to get the idea ;)
Just drop the code into a new project with a windows form... ie, replace the code file generated by Visual Studio. My form size was 500x500, but you can do whatever you want I suppose. - public partial class Form1 : Form
-
{
-
private List<Circle> m_objList = new List<Circle>();
-
private Circle m_circleGettingMoved = null;
-
private Vector m_offset = null;
-
-
public Form1()
-
{
-
InitializeComponent();
-
-
m_objList.Add(new Circle(new Vector(100, 100), 50, Color.Purple));
-
m_objList.Add(new Circle(new Vector(250, 150), 25, Color.Green));
-
}
-
-
protected override void OnPaint(PaintEventArgs e)
-
{
-
base.OnPaint(e);
-
-
Graphics g = e.Graphics;
-
foreach (Circle obj in m_objList)
-
{
-
obj.Draw(g);
-
}
-
}
-
-
private void Form1_MouseMove(object sender, MouseEventArgs e)
-
{
-
if (e.Button == MouseButtons.Left && m_circleGettingMoved != null)
-
{
-
m_circleGettingMoved.Position = new Vector(e.X + m_offset.X, e.Y + m_offset.Y);
-
this.Invalidate();
-
}
-
}
-
-
private void Form1_MouseDown(object sender, MouseEventArgs e)
-
{
-
if (e.Button == MouseButtons.Left)
-
{
-
if (m_circleGettingMoved == null)
-
{
-
Vector mousePoint = new Vector(e.Location.X, e.Location.Y);
-
foreach (Circle circle in m_objList)
-
{
-
float dist = Vector.Distance(mousePoint, circle.Position);
-
if (dist <= circle.Radius)
-
{
-
m_circleGettingMoved = circle;
-
m_offset = new Vector(circle.Position.X - e.X, circle.Position.Y - e.Y);
-
break;
-
}
-
}
-
}
-
}
-
}
-
-
private void Form1_MouseUp(object sender, MouseEventArgs e)
-
{
-
if (e.Button == MouseButtons.Left && m_circleGettingMoved != null)
-
{
-
Circle moveCircle = m_circleGettingMoved;
-
-
foreach (Circle circle in m_objList)
-
{
-
if (circle != m_circleGettingMoved)
-
{
-
int totalDist = circle.Radius + moveCircle.Radius;
-
if (Vector.Distance(circle.Position, moveCircle.Position) < totalDist)
-
{
-
Vector line = new Vector(moveCircle.Position.X - circle.Position.X, moveCircle.Position.Y - circle.Position.Y);
-
line.Normalize();
-
Vector newPos = new Vector(
-
circle.Position.X + totalDist * line.X,
-
circle.Position.Y + totalDist * line.Y);
-
-
moveCircle.Position.X = newPos.X;
-
moveCircle.Position.Y = newPos.Y;
-
this.Invalidate();
-
}
-
}
-
}
-
-
m_circleGettingMoved = null;
-
}
-
}
-
}
-
-
public class Vector
-
{
-
public float X { get; set; }
-
public float Y { get; set; }
-
-
public Vector(float x, float y)
-
{
-
X = x;
-
Y = y;
-
}
-
-
public static float Distance(Vector A, Vector B)
-
{
-
return (float)(Math.Sqrt((A.X - B.X) * (A.X - B.X) + (A.Y - B.Y) * (A.Y - B.Y)));
-
}
-
-
public float Length()
-
{
-
return (float)(Math.Sqrt((X * X) + (Y * Y)));
-
}
-
-
public void Normalize()
-
{
-
float absLength = Math.Abs(Length());
-
X = X / absLength;
-
Y = Y / absLength;
-
}
-
-
public override string ToString()
-
{
-
return string.Format("(X={0}, Y={1})", X, Y);
-
}
-
}
-
-
public interface IDrawableObject
-
{
-
Vector Position { get; set; }
-
void Draw(Graphics g);
-
}
-
-
public class Circle : IDrawableObject
-
{
-
private Vector m_center;
-
-
public Vector Center
-
{
-
get { return Position; }
-
set { Position = value; }
-
}
-
-
public int Radius { get; set; }
-
-
public Color Color
-
{
-
get { return m_pen.Color; }
-
set { m_pen.Color = value; }
-
}
-
-
private Pen m_pen = new Pen(Color.Black);
-
-
public Circle(Vector center, int radius, Color color)
-
{
-
Center = center;
-
Radius = radius;
-
m_pen.Color = color;
-
}
-
-
#region IDrawableObject Members
-
-
public void Draw(Graphics g)
-
{
-
if (g != null)
-
{
-
g.DrawEllipse(m_pen, m_center.X - Radius, m_center.Y - Radius, Radius * 2, Radius * 2);
-
}
-
}
-
-
public Vector Position
-
{
-
get
-
{
-
return m_center;
-
}
-
set
-
{
-
m_center = value;
-
}
-
}
-
-
#endregion
-
}
I did this with circles and I'll leave it to you to figure out how to do it with rectangles. If you don't care about them meeting at the edges, you can just pretend the radius is the max of the width or the height, really.
Just run the code and click/hold to drag the circles around. Release the circle to stop dragging. If the circle overlaps the other, it will move outside along the direction between the centers.
This is a cheezy gdi implementation, so try not to judge me too harshly ;) Let me know if you have any questions!
*Edit: Oops! I just realized you'll need to manually hook up the events as well. They're appropriately named though so make sure you put the form events to the correct one.
Sign in to post your reply or Sign up for a free account.
Similar topics
by: dev1null2 |
last post by:
Hi!
I'm using window.open to create a secondary window, and everything is
working fine with that. My problem is that as soon as that window is
opened, the parent window scrolls to the top of...
|
by: Spammay Blockay |
last post by:
Hi all...
I'm writing a Struts application, and one window pops up another,
non-modal, window.
What I want to do is, when the user presses a button on the child
window, I want the parent...
|
by: KenG |
last post by:
Hi:
I have a datagrid that builds a hyperling which uses javascript to
open a new window. The new window opens and displays fine, however,
the original window that has the grid, is now blank...
|
by: Sileesh |
last post by:
Hi
I have a btn in Parent.aspx page . On server_click() of the Btn, i am
opening a new window called the child.apsx window. Child window also have a
Btn. On serverClick of this Btn, I perform...
|
by: kebabkongen |
last post by:
Hi,
I am working on an application where I make a popup window with a long
list of users (with checkboxes)
I am trying to figure out how to pass the list of selected users to the
parent window....
|
by: javanet |
last post by:
Hi all,
1) i opened a parent window.
2) then i opend a child window thruogh this parent window.
Now i want to close child window before closing the parend window
means my clients can not be...
|
by: rishhi04 |
last post by:
how to pass jsp child window value to parent jsp window .particular field or focus field
|
by: Bhishm |
last post by:
Hi,
I am opening a child window from parent using window.open, but on
refreshing the parent the reference of the child is lost.
Is there any way to save the reference of the child in the...
|
by: dummy07 |
last post by:
Is it possible to close a modal window from the parent window???
Please help..
|
by: nitindel |
last post by:
Hi
Guys...
I am looking for a functionality of closing the POP UP window that i have opened from a Parent window....Whenver i Close the Parent window..
I mean to say...
Whenver i close...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
| |