I have a project that is using WPF Drag and Drop built in functionality. I'm using the OnGiveFeedback event override to change the cursor when the draggable item is inside a droppable item.
My issue is that the control I'm trying to isolate the drag and drop to is embedded in an area that also contains HTML on the sides. When I drag over the HTML area, my cursor changes like it is over a drop area.
I'm trying to remedy this by getting the mouse position when my DragDropEffect = DragDropEffect.Move inside my OnGiveFeedback override, and making sure the mouse is still within the bounds of my control.
I can't seem to find a way to get the mouse position from inside this override. Mouse.Position is returning the point where my Drag started so I'd assume the mouse events get blocked once a drag operation starts.
Any insight would be greatly appreciated.
Code Snippet:
protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
{
// These Effects values are set in the drop target's
// DragOver event handler.
if (e.Effects.HasFlag(DragDropEffects.Move) || e.Effects.HasFlag(DragDropEffects.Copy))
{
Mouse.SetCursor(Cursors.Cross);
}
else
{
Mouse.SetCursor(Cursors.Arrow);
}
e.Handled = true;
}
why don't you override OnDragEnter and OnDragLeave and change the cruser from there.
Related
I am trying to implement a DRAG DROP event in windows form. The Drag event starts when I select some text in text box, click and hold the right mouse button and start dragging the text from the text box, passes over a panel(Right mouse button still hold/clicked) and then the dragged text has to be dropped over a tree view(release right mouse button).
I want my mouse cursor to change when i am dragging over the panel control. The Cursor do change to my expected cursor icon as of now but it flickers a lot and cursor image is not constant.
I am implementing the logic in Drag Over event handler which i think gets fired again and again automatically while dragging and this results in flickering or some sort of refreshing.
My implementation is as follows:
ABC.Desginer.cs:
this.splitterPanel.DragOver += new System.Windows.Forms.DragEventHandler(this.splitterPanel_DragOver);
ABC.cs:
private void splitterPanel_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
Bitmap bmp = new Bitmap(ABC.DefInstance.ImageList1.Images[3]);
Cursor c = new Cursor(new Bitmap(bmp, 32, 32).GetHicon());
frmFlat2Obj.DefInstance.splitterPanel.Cursor = c;
DestroyIcon(c.Handle);
}
}
My question is: How exactly shall I stop or reduce the mouse cursor flickering while dragging over the Panel??
THANKS IN ADVANCE :)
I have written a custom Control, based on other code, which includes a call to SetStyle(ControlStyles.Selectable, false);
This prevents the following code from being called (which works if I remove the above line and click on the Control first to 'focus' it):
protected override void OnMouseWheel(MouseEventArgs e)
{
ScrollBar.Value = Math.Min(ScrollBar.Value - e.Delta, ScrollBar.Maximum - ScrollBar.LargeChange);
LayoutChanged();
}
My control does not need focus so Selectable=false is correct.
What do I need to do so that I can run this code whenever the mouse is over my control and the MouseWheel is moved regardless of where the focus is?
Thanks for the comments. A additional info:-
I am running Windows 7 but any solution must work on any OS.
The Control is inherited via Control/ControlBase/BaseControl/BaseStyleControl where the latter 3 are DevExpress controls.
The real focus should not be changed just because the cursor hovers over my control
There are no child controls other than a scrollbar (an inherited DevExpress one) which is normally invisible and shows itself when the mouse hovers over where it would be when visible.
The control does nothing but draw itself (imagine a number of bookshelves one under the other with book covers drawn on them - the number of shelves increases to accommodate all the books and the scrollbar allows all to be scrolled into view.
Since this is a use-anywhere Control, getting MouseWheel events from a Parent that knows about its requirements isn't a good idea.
Maybe there is a way of registering for a first-look (is that a MessagePreview?) to pinch MouseWheel events before normal processing happens.
I have created a custom control.
I have drawn a text inside the control.
In that, I'm trying to change the default cursor to Hand cursor when moving the mouse pointer on a particular region(Region where the text drawn inside the control).
For that, I have changed the cursor on the MouseMove event of the control.
if (textRect.Contains(e.Location))
{
Cursor.Current = Cursors.Hand;
}
I'm getting a flickering effect when moving the mouse over the control.
That is, the cursor is changed to hand cursor and back to default cursor.
I can't able to figure out why it is happening.
Provide your valuable suggestions to resolve this.
Thanks in advance.
Am having a problem in scrollviewer.
Scenario:
am having a stack panel inside which having a content, from mouse move of that content am showing a popup to rearrange those content.
issue: when am trying to handle mouse move of that content popup shows and also scrolling happening.
expected behavior: scrolling should not happen while handling mouse move.
i have tried "HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled" it works fine but it sets the scrollviewer to its initial position, means horizontal offset sets to Zero("0")
thanks in advance.
As per our discussion, I think the best route would be to store a class level boolean which will determine whether or not to enable scrolling. You'd have to set this according to your needs (Probably the same place you were modifying the visibility before).
The next step would be to set up some events and properties on your scrollviewer so that you can control whether it scrolls or not. You really only need to modify the constructor of the page holding the scrollviewer, and create a handler for the ManipulationStarted event. The following assumes your control is named Scroll, and that the variable locked is set to true when the control should not scroll:
public MainWindow()
{
InitializeComponent();
Scroller.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(scroller_ManipulationStarted);
Scroller.ManipulationMode = ManipulationMode.Control; // Required
}
void scroller_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
if (locked)
{
e.Handled = true;
e.Complete();
}
}
I have a UserControl that listens to it's own MouseLeave in order to change it's background color and some of it's children visibility.
The children that should lose visibility, also listen their own MouseLeave in order to change their background color.
A scenario in which everything works is this:
Move mouse into UserControl.
Move mouse into Child.
Move mouse out of Child into UserControl.
The problematic scenario is this:
Move mouse into UserControl.
Move mouse into Child.
Move mouse out of Child, not into the UserControl, but directly outside of it.
This scenario happens all the time since the Child is located at the very edge of the UserControl.
Note that not only the UserControl's MouseLeave doesn't fire, but neither does the Child's MouseLeave.
In order to find out whether the mouse has actually left the area in this case, I must listen to MouseEnter of other controls, and then notify the UserControl and Child, but I really want to avoid this solution, since it is ugly and not OOPish.
Also, the Child MUST be located at the very edge of the UserControl, and cannot move.
Can anyone think of a neat solution to the problem?
My tests show this as a working solution. Just requires a custom user control.
public class MyPanel : Panel
{
protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.MouseLeave += DidMouseReallyLeave;
base.OnControlAdded(e);
}
protected override void OnMouseLeave(EventArgs e)
{
DidMouseReallyLeave(this, e);
}
private void DidMouseReallyLeave(object sender, EventArgs e)
{
if (this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
return;
base.OnMouseLeave(e);
}
}
I've seen the same behavior before. Is your .NET version up-to-date? Be sure you're on the latest service packs.
Have you seen the event Application.AddMessageFilter? I used that in an answer here to catch mouse messages and handle them more intelligently. It might come in handy here.
This isn't how MouseLeave is supposed to behave. You should get the MouseLeave event even if the mouse cursor moves our of your application window entirely.
I'm guessing you're not calling the base method in your MouseLeave handler.
Anyway, on MouseEnter you can set a timer that fires every 0.25 second, and in it check if the mouse is still over the control. If it isn't, kill the timer and change the control's color.