how capture a moving customcontrol - c#

I try to explain my problem:
I got many customcontrols of same type on a panel.
At runtime I'm free to move any custumcontrol ( mousedown and mousemove events) in the form with mouse over any others customcontrols using bringtofront() to have it over all.
Now I need to know when the control I'm moving is over any other control and which control is under.
So far I've tryed to use drag-n-drop events but without success, there's some other way to do this or I've to re elaborate it with drag events?
thank you all for help
and sorry for my English.
EDIT:
The controls are cards game and my final goal is to use cards to create logical sequence following rules based on card value and/or color.

You can't solve the problem with drag-and-drop because you're not actually dropping one control onto the other control. You're merely moving them around in the form.
You need to become familiar with Z order, which is the front-to-back arrangement of objects in a virtual 3D space. To adjust the Z order, you can call the BringToFront and SendToBack methods of any object that derives from System.Windows.Forms.Control.
The Z order is also exposed by the parent (container) control's Controls collection. Using the GetChildIndex method, you can determine the position of any control within the Z order.
So now, all you need to do is figure out which control the control you're dragging is over. Do that by comparing the Location properties of the two controls. When you know that the locations of two controls overlap, check their respective Z order indices to see which one is on top.

Related

Get index of control located in e-th coordinates

I have a flowLayoutPanel on my form. I have some controls there which can be dragged and dropped . What I need is to get the index of the control, which is located on mouse position, for example if mouse is on the first widget, I have to get 0. Please show me some way how can I do it.
Thanks
EDIT
Frogot to upload the photo ,sorry
You will need to iterate through the controls in the flowLayoutPanel.Controls collection to find which control is under the mouse. Then iterate through the list again to find how many controls are above/equal height and to the left of the control in question.
I don't think you can avoid the 2 iterations, as the ordering of the collection is not tied to physical position.
I realize this is a 5-year old question, but since this question and answer still pop up in Google, I feel compelled to provide a genuine answer.
The FlowLayoutPanel class provides a method called GetChildAtPoint which takes a client-relative location and returns the control at that position (if the position is the mouse location relative to the FlowLayoutPanel window, then that identifies the control under the cursor). Worse case, then, you only have one linear search iteration through the FlowLayoutPanel's children to match objects (if in fact, your objective is to get the actual index instead of finding the index to look up the control; if finding the control is what you actually want, you are already done).
In my particular application, I needed to track things easily in a drag-drop scenario where a control could only be dragged within a range of related controls. So I used the "Tag" property to populate the index into the control itself as I was populating the panel (actually I stored a reference to the base class of my child control wrappers, and maintained the index in a base-class Property that I could query after casting the Tag to the base class, but I digress. The reference allowed me to get all kinds of cool information about the window under the cursor for appropriate display and/or manipulation in addition to maintaining the parent index).

How to check if two controls are overlapping in Windows Forms

I have created a class that allows the user to drag panels on a forms. How can I ensure
that the user does not place two panels on top of each other? If they do, I would like to shift/or highlight one of the control while they are both overlapped.
I tried setting this in OnMouseDown event but that didn't quite work.
Also, the number of panels on the form vary depending on the number of pictures the form needs to show. Each panel has a picturebox inside the panel.
A much better approach is to use the Rectangle.Bounds.IntersectsWith method, which does the check for you and can produce cleaner code. I'm personally unaware of any performance issues or benefits, one way or the other, although I would venture a guess that simply looping over your controls and checking them with this would be faster than building lists and loops both.
Picturebox pic = new Picturebox();
foreach(Control picturebox in Form1){
if (pic.Bounds.IntersectsWith(picturebox.Bounds))
{
//We have a problem, Houston, because we just collided!
}
}
I hope this helps, even though you asked this question some time ago.
So I was able to solve this question with the help of sgud's suggestion.
The trick was to use Rectangle.Intersect method inside OnMouseUp event raised.
Here is the intuition I used behind it. (it might not be the neatest solution)
1) Create a list of all the controls inside my main panel.
2) Traverse through the controls and create a list of all the Rectangle Bounds for each control. you can get this by control.Bounds
3) Go through the list of Bounds and intersect it with the currently active element's bound.
If the returned rectangle has height and width the same as the active control then assign change the back color property.
I hope this helps to anyone else that have a similar problem

How to center selected grid row/column at the center of the window?

I just wasted my entire evening on something which I thought would be very simple but it seems WPF and Google are letting me down completely.
I need a grid, 6x6 of which I fill every row and column with a custom control. I want to be able to navigate through this grid via the keyboard (I can get those events, no problem) but I cannot seem to find how I can always have the selected grid row/column in the center of my window.
I found some carousel alike implementations, but most of them only work in a single direction and I want two way navigation, yet none seem to support this nor can I extend them to do this.
I essentially want to create a PSP alike grid navigation.
One easy way is to do this:
Create a scrollable form.
Add a 6x6 grid of child controls.
In the GotFocus (or similar) event for all the controls, set the parent form scroll offset to an appropriate position to centre the child.
This is pretty straight-forward thing to implement, with a little bit of maths to work out how to centre the x,y position of a control by setting the scroll offsets (it can be tricky/confusing, but as long as you understand the coordinate systems used for scrolling, not too bad)
Or, another approach that avoids scrolling via the windows APIs and using custom controls:
Create a form
Override OnPaint to draw your grid of 6x6 "controls" as simple graphical shapes or bitmap images centred on the selected "control".
Handle keyboard (KeyDown/Up) and mouse handling (MouseDown/Up) events to make the 36 areas of the graphic respond to user inputs in the way you desire. You'll have to track the selected item and force the window to redraw its graphics to show the new state. Enable double buffering to stop it flickering.
The first approach gives you a lot of windows-based handling for free (tabbing between controls, remembering where the input focus is, and directing events to separate classes for each "control", for example). The second approach strips away all this "help" but gives you complete control over everything, which can often help avoid unintended behaviours (e.g. it won't move the input focus when the user presses Tab unless you specifically write the code to make it do that).

C# Only refresh PictureBox/Panel when tell them to refresh?

I'm making a bomberman game in a C# windows form application. It has over 300 pictureboxes (walls) that are placed on a panel. The picturebox of bomberman himself is also on that panel.
When the location of bombermans picturebox changes, all the controls on the panel are automatically refreshed. Because there are so many controls on that panel, and because the location of the picturebox changes multiple times per second, the program becomes laggy when I try to move.
I want to have control over the refresh event of the panel (and it's controls), because I think my problem is solved when only the pictureboxes that need to be refreshed, are refreshed programmatically.
I hope someone can help me out with this!
Ruud.
If you move the child, the parent has to be refreshed because it may need to draw the area where child was located previously. It would also mean that all children (of parent) would get refreshed.
OTH, using so many controls may not be a good idea. I would suggest you to keep data structures describing walls and then use it to draw it within Panel (or your custom control). You can write your own logic for hit testing (mouse or keyboard click within wall boundary) by capturing mouse/keyboard events at Panel/Parent level. With correct organization data structure, hit testing can be very efficient.
You are trying to paint the whole form which will surely take time . If you want to change only a part of the form, which in your case is Moving the bomberman to a new position, Only invalidate the area you want to repaint and then pass it to the Invalidate method.
Do something similar to this.
//Invalidate previous position of bomberman
Rectangle invalid = new Rectangle(picturebox1.Location.x,picturebox1.Location.y,picturebox1.Width,picturebox1.Height);
Invalidate(invalid);
//Add code to move your picture box and then call above two lines again
invalid = new Rectangle(picturebox1.Location.x,picturebox1.Location.y,picturebox1.Width,picturebox1.Height);
Invalidate(invalid);
Note sure but somthing similar polished code would work...
Here is a link to an example for reference. http://msdn.microsoft.com/en-us/library/ms229628.aspx

c#/java Drag points and draw lines between them

Hey,
is there a a simple way in c# or java to let the user "drop" points onto the form and then draw lines between the new point and existing ones ?
with simple way i mean a component/framework/whatever (or even already existend in c#/java ?)
Sure; it'll be framework and architecture dependent though. C# WPF will have a different way to do it then C# WinForms which will be different than Java Swing.
For Winforms, you'll simply create a Graphics object based on some area of your form bounded by a control (like a Panel or PictureBox), then on that Control's MouseClick event, log the mouse's current location and draw a line between that location and the location of the previous click (or all other clicks).
If you want to drag and drop, like from a toolbar, that's a little more complex; basically you need to track what you dragged and where you dropped it so when you drop it you can perform the proper action. I believe the arguments you'll get in the DragDrop handler will give you this information.
I am not aware of any lib that does that, but what I did to simplify things a bit is created usercontrol 2x2 which represented a point and allowed user to drop it onto form by drag and drop. Lines were drawn manually, however, in OnPaint(...)

Categories