c# Prevent dragging box over another - c#

I am using visual studio. In my program I have the option for a user to activate certain widgets that they want to have. Each widget is a UserControl, so when they click to show a widget, it is activating the corresponding user control. Once they activate the control, they can drag the boxes wherever they wish so that they can customize how their screen looks. However, whenever you drag one widget over another, it just stacks them on top of each other, and this is not what I want. If I am dragging a box and it touches another one, I want it to stop and not be able to overlap it. How can I do this? I suspect it has something to do with the "DragOver" event, but not for sure.

The DragOver event will be raised on these case :
[+] If the user moves out of a window, the DragLeave event is raised.
[+] If the mouse enters another control, the DragEnter for that control is raised.
[+]If the mouse moves but stays within the same control, the DragOver event is raised.
If this is the event that you want, so try to terminate the widget (User Control) on UserControl_DragOver.
You can terminate your UserControl like this :
private void Btn_Cancel_Click(object sender, EventArgs e)
{
this.Parent.Controls.Remove(this);
}
(If you mean sth else, tell in comment)

Related

Activate Click and MouseDown events at the same time?

I am trying to create a form where the user selects one of 2 radio buttons, "fast" and "slow", then presses a "go" button on the form. It should work as follows:
When "fast" is selected and "go" is pressed, the user needs to continue holding down the button in order to make the player move and the player stops when the user releases their finger from the button. For this, I am using the MouseDown and MouseUp events.
If "slow" is selected, the user can only move one step at a time, regardless of how long the button is held down. for this, I am using the Click event.
To test this concept, I put a MessageBox in the Click and MouseDown events to see how they work together. When I click on the button, however, I am only seeing the Mousedown event get triggered, regardless of which radio button is selected and the Click event is only triggered when the go button is in focus and I press enter.
How can I make it so that both events get called simultaneously (and then I can put the respective if statement in to differentiate between "fast" and "slow" radio buttons)? (The button is wired up to these events by double-clicking on their respective handler in the design window, not hardcoded).
private void go_button_MouseDown(object sender, MouseEventArgs e)
{
Console.WriteLine("Mousedown"); // Doesn't show in console window in Release mode, still trying to solve this
MessageBox.Show("Mosuedown");
}
private void go_button_Click(object sender, EventArgs e)
{
Console.Out.WriteLine("go_buttonclick"); // Doesn't show in console window in Release mode, still trying to solve this
Console.WriteLine("go_buttonclick"); // Doesn't show in console window in Release mode, still trying to solve this
MessageBox.Show("go_buttonclick");
}
I found what I was doing wrong, both events are being triggered at the same time, but the MessageBox in the MouseDown event wasn't allowing me to see the Click and MouseUp events also being triggered. When I turned off the MouseDown MessageBox, the other 2 MessageBoxes appeared, thanks!

Adding Click Handler On UserControl Breaks Click On Children

I have a user control that I'm trying to make draggable. The whole control should be draggable except when you click on buttons or text boxes. I'm handling the mousedown, mouseup and mousemove events on the usercontrol itself and I can drag by clicking anywhere. The only issue is now I can't click any buttons on the user control. Any clue what's going on?
Code is something like this:
<UserControl PreviewMouseLeftButtonDown="Popup_PreviewMouseLeftButtonDown" ....STUFF...>
<!-- CAN'T CLICK THIS -->
<Button />
<UserControl>
Code Behind:
public void Popup_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
{
mouseDown = true;
oldMousePosition = this.PointToScreen(e.GetPosition(this));
this.Popup.Child.CaptureMouse();
}
The issue arises when you use CaptureMouse() - this permanently captures all your mouse input on the window, and makes it so that you're unable to click on anything within the Window. I don't know if it's different for you, or if you checked, but it's not (just) that the Button is unclickable - it's that literally everything on the Window is unclickable.
You have to actually do something with the mouse after you've captured it, and then once you finish that, you have to return normal control by calling Mouse.Capture(null). For you, this would probably be best to do in your MouseUp() method.
However, this still leaves the child problem. I can't really think of any way you're going to be able to both capture all mouse click events on a parent control and allow them to get to the child control. I suppose you could check the mouse position against the button position, both relative to the UserControl, then route the click event to the Button every time, but this seems a little overelaborate. Is there a reason you can't just add a full-sized Grid to the UserControl with a lower ZIndex than the Button, and just use that to detect if a click was made inside the UserControl but not on the Button?

WinForms Event Parent scroll

I have two FlowLayoutPanels on a form: PanelA and PanelB. Each will be populated at run-time with multiple controls, such that the panel will scroll (i.e AutoScroll is true).
Here's the issue: The controls that the panels are populated with each contain a ComboBox. Thus, MouseWheel events are consumed by the combo box instead of by the panel. I want MouseWheel events to be consumed by the panel.
If there's no scrollable control on the child controls, then the MouseWheel event skips the child control (which doesn't handle it) and hits the panel, which does handle it. How can I set my child control's combo box to ignore the MouseWheel event? Can I tell it to re-raise the event?
I tried just applying Focus to the Parent whenever one of the child controls ticks the 'MouseEnter' event; this fixed the scrolling issues, but also left the child controls completely un-editable.
Something else I've found from digging around involves fiddling with the Windows API directly, but I find it hard to believe that something like that is required for this.
I tested the following code and it seems like a solution to your issue. Basically you need to focus the 'FlowLayoutPanel' when you click on it, or your mouse enters it:
private void newCheckListQuestionPanel_Click(object sender, EventArgs e)
{
newCheckListQuestionPanel.Focus(); //allows the mouse wheel to work after the panel is clicked
}
private void newCheckListQuestionPanel_MouseEnter(object sender, EventArgs e)
{
newCheckListQuestionPanel.Focus(); //allows the mouse wheel to work after the panel has had the mouse move over it
}
Source

How to bypass the enter/leave event in c sharp

I'm having a Picture box in a user control window(Windows custom control library). and some functionality in the Form's Enter event and leave event.
Now my sample application is having two instances of the control. So when i run my sample application the fist control got selected and the enter event is triggered, and when i select the second control the first's leave and second's enter events are getting triggered.
Now, problem is that when i select(click) the second control's picturebox, the events are not triggering, i.e the control form is not getting the event.
So if i click whereever in the control(in the picturebox or in the control) the enter event should be triggered.
How to do this?
A picture box can't get focus. So clicking on it won't take the focus away from the previous control thus not triggering the events.
You need to add a click handler on the picture box in which you manually give focus to the associated focusable control.
private void PictureBox_Click(object sender, EventArgs e)
{
focusableControl.Focus();
}

How to do two things with one click in Windows Form

On my main form, there is another (floatable) window. This floatable window works sort of like a popupwindow in that it will close when the user clicks somewhere else outside of this window. This is handled by the Deactivate event. But what I want to do is, if the user clicks on a different control (say a button), I want to both close this float window and then activate that button with just one click. Currently, the user has to click twice (one to deactivate the window and once more to activate the desired button). Is there a way to do this with just one click?
foreach(Control c in parentForm.Controls)
{
c.Click += delegate(object sender, EventArgs e)
{
if(floatyWindow != null && floatyWindow.IsFloating)
{
floatyWindow.Close();
}
};
}
And then add your handlers as normal. This additional handler can close the floaty window.
Make sure you floaty window isn't a dialog too as this will not allow your parent form's controls to be clicked.
I had a slightly hacky solution. In your Deactivate event, fire another custom event to your main form. Then when you main form is handling the custom event, enumerate through your control(this.Controls) and locate the control under the mouse by checking all their bound then call Focus(). You might need to sort by the one with the smallest surface area, or you can have a separate list of "focus-able" control like button just for this purpose.
Another way might be to switch focus to your main form immediately after OnMouseLeave of the floatable window, or OnMouseHover of your main window, but keep the floatable windows on top, just no focus. Handle the global mouse down of your main form, and close the floatable window by then.
These are just theories, not tested.
I had an issue like this once too, when a customer wanted "floaty" windows all over there application. I used used an approach similar to the one described in this article:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp
Code sample available here:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/Popup_Form_Demonstration.asp
By extending this a bit we created "floaty" windows similar to the ones VS uses when you get a runtime error while debugging code.
At the very least reading the code may give you some insight, however, quarrelsome's response may be the more simple solution.

Categories