Here's my code:
public AbilitiesController(Abilities page)
{
_page = page;
page.ScrollBar.MouseLeftButtonDown += MouseDown;
page.ScrollBar.MouseLeftButtonUp += MouseUp;
page.ScrollBar.MouseLeave += MouseLeave;
page.ScrollBar.MouseWheel += MouseWheel;
page.ScrollBar.MouseMove += MouseMove;
}
private void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{
if (!_dragBound) return;
var newPos = mouseEventArgs.GetPosition(_page);
var dPos = newPos - _pos;
_page.ScrollBar.ScrollToHorizontalOffset(dPos.X);
_page.ScrollBar.ScrollToVerticalOffset(dPos.Y);
_pos = newPos;
Console.WriteLine("Moved");
}
private void MouseWheel(object sender, MouseWheelEventArgs mouseWheelEventArgs)
{
Console.WriteLine("MouseWheel");
}
private void MouseLeave(object sender, MouseEventArgs mouseEventArgs)
{
_dragBound = false;
Console.WriteLine("Left");
}
private void MouseUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
_dragBound = false;
Console.WriteLine("Mouse Up");
}
private void MouseDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
_dragBound = true;
Console.WriteLine("Click!");
}
Page is a Page, Scrollbar is a Scrollview.
I know my logic for moving the scrollbar probably isn't correct yet, but we aren't even getting that far yet.
For some odd reason the MouseDown event isn't firing whether I bind it to MouseDown or MouseLeftButtonDown.
However oddly enough the MouseUp event works no problem.
Which seems really odd because normally if one is broken, the other is too...
Using latest version of Visual Studio 2017 in a WPF project.
You might want to try 'PreviewMouseDown' instead of 'MouseDown' and same for all the other non-working mouse events, as they may already be being handled by whatever the base class of your 'Abilities' class is.
Related
I am trying to start a drag and drop on a Button control in WPF. I am using Button because I also want to handle click event.
Adding a Button in XAML and handling the MouseMove event always has e.LeftMouse equal to MouseButtonState.Released.
<Button MouseMove="Button_MouseMove"/>
In the following handler implementation the exception is never thrown.
private void Button_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
throw new Exception("It works!");
}
I noticed the same is true for any control I place inside a Button and try to process MouseMove event.
How do I handle drag and drop from a Button control or any other control inside a button in WPF?
EDIT - Solution based on mm8's answer
The updated XAML is:
<Button PreviewMouseDown="Button_PreviewMouseDown"
PreviewMouseUp="Button_PreviewMouseUp"
PreviewMouseMove="Button_PreviewMouseMove">
</Button>
The updated handler code:
Point startPosition;
double delta = 10;
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
startPosition = e.GetPosition(this);
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Point currentPosition = e.GetPosition(this);
if ((currentPosition - startPosition).Length < delta)
throw new Exception("MouseClick");
}
private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point currentPosition = e.GetPosition(this);
double currentDelta = (currentPosition - startPosition).Length;
if (e.LeftButton == MouseButtonState.Pressed && currentDelta >= delta)
throw new Exception("DragAndDrop");
}
You could perhaps handle the PreviewMouseDown event instead of Click:
private void Button_Click(object sender, MouseButtonEventArgs e)
{
//handle click here...
e.Handled = true;
}
XAML:
<Button PreviewMouseDown="Button_Click" MouseMove="Button_MouseMove"/>
I am trying to implement a two-finger swipe gesture for multi-selection of GridView. But I can't receive required pointer events for counting the number of fingers which are touching the screen. I am testing with Dell P2314T during development.
The order of pointer event fireing:
Theoretical:PointerPressed(pressed)=>PointerMoved(swiping)=>PointerReleased (released)
Actual:PointerPressed & PointerCaptureLost (when pressed but not released)
PS: The demo is removed.
Here is a snippet of my code, which obviously doesn't work because PointerMoved and PointerReleased don't fire:
class CustomGridView : GridView
{
List<uint> pointerPoint = new List<uint>();
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
(element as GridViewItem).AddHandler(PointerPressedEvent, new PointerEventHandler(OnPointerPressed), true);
(element as GridViewItem).PointerMoved += OnPointerMoved;
(element as GridViewItem).PointerReleased += OnPointerReleased;
base.PrepareContainerForItemOverride(element, item);
}
private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
if (!pointerPoint.Contains(e.Pointer.PointerId))
{
Debug.WriteLine("add:" + e.Pointer.PointerId);
pointerPoint.Add(e.Pointer.PointerId);
}
}
private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
if (pointerPoint.Count == 2)
{
Debug.WriteLine("two finger");
}
}
private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
if (pointerPoint.Contains(e.Pointer.PointerId))
{
Debug.WriteLine("rem:" + e.Pointer.PointerId);
pointerPoint.Remove(e.Pointer.PointerId);
}
}
}
This is my solution:
Base on observation, ScrollViewer will capture the remaining pointer events.
ScrollViewer should be disabled and ongoing direct manipulation should be canceled when PointerPressed is fired.
XAML:
<GridView ScrollViewer.VerticalScrollMode="{x:Bind GridViewScrollMode}"/>
C#:
private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
pointerPoints.Add(e.Pointer.PointerId);
if (PointerIds.Count == 2)
{
((sender as GridView).ContainerFromIndex(0) as GridViewItem).CancelDirectManipulations();
GridViewScrollMode = ScrollMode.Disabled;
}
}
I am trying to make my Form, which has no border, moveable with holding the left mousebutton down and exit the while loop, when releasing the mousebutton.
But the code I have right now doesn't exit the loop on release.
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
while (mouseDown)
{
mouseX = MousePosition.X;
mouseY = MousePosition.Y - 30;
this.SetDesktopLocation(mouseX, mouseY);
if (e.Button != MouseButtons.Left)
mouseDown = false;
}
I also tried to add a mouseUp event but it cant happen as long as mouseDown is active.
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = true;
}
OK, I fixed it for myself.
I just did this:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
mouseX = MousePosition.X - 20;
mouseY = MousePosition.Y - 40;
this.SetDesktopLocation(mouseX, mouseY);
}
}
By using a loop in the on mouse up event you are locking the thread. You could use the MouseMove event with a public variable to check if the mouse is down.
I'm looking for a way to determine which item in a toolStrip that was dragged after a DragDrop event has occured, all I want to do is make a switch case with different cases for each item in the toolstrip but I cant seem to find a way of comparing them.
UPDATE: SHORT CODESAMPLE
private void toolStrip1_DragDrop(object sender, DragEventArgs e)
{
//Here I want something like a DoDragDrop() and send the specific item from the
//toolstrip..
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
//And here some way to determine which of the items was dragged
//(I'm not completely sure if I need a mouseUp event though..)
}
Hopefully a bit easier to get what I'm trying to do.
The events in your example don't look like the correct events to use.
Here is a working example from a ToolStrip that has 2 ToolStripButtons on it:
public Form1() {
InitializeComponent();
toolStripButton1.MouseDown += toolStripButton_MouseDown;
toolStripButton2.MouseDown += toolStripButton_MouseDown;
panel1.DragEnter += panel1_DragEnter;
panel1.DragDrop += panel1_DragDrop;
}
void toolStripButton_MouseDown(object sender, MouseEventArgs e) {
this.DoDragDrop(sender, DragDropEffects.Copy);
}
void panel1_DragEnter(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Copy;
}
void panel1_DragDrop(object sender, DragEventArgs e) {
ToolStripButton button = e.Data.GetData(typeof(ToolStripButton))
as ToolStripButton;
if (button != null) {
if (button.Equals(toolStripButton1)) {
MessageBox.Show("Dragged and dropped Button 1");
} else if (button.Equals(toolStripButton2)) {
MessageBox.Show("Dragged and dropped Button 2");
}
}
}
we able to move windows forms when we mouse down on title bar .
but how can I move windows when mouse down in form ?
You'll need to record when the mouse is down and up using the MouseDown and MouseUp events:
private bool mouseIsDown = false;
private Point firstPoint;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
firstPoint = e.Location;
mouseIsDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
As you can see, the first point is being recorded, so you can then use the MouseMove event as follows:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseIsDown)
{
// Get the difference between the two points
int xDiff = firstPoint.X - e.Location.X;
int yDiff = firstPoint.Y - e.Location.Y;
// Set the new point
int x = this.Location.X - xDiff;
int y = this.Location.Y - yDiff;
this.Location = new Point(x, y);
}
}
You can do it manually by handling the MouseDown event, as explained in other answers. Another option is to use this small utility class I wrote some time ago. It allows you to make the window "movable" automatically, without a line of code.
Listen for the event when the mouse button goes down in the form and then listen for mouse moves until it goes up again.
Here's a codeproject article that shows how to do this: Move window/form without Titlebar in C#
You can't use location provided in MouseUp or Down, you should use system location like this
private Point diffPoint;
bool mouseDown = false;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
//saves position difference
diffPoint.X = System.Windows.Forms.Cursor.Position.X - this.Left;
diffPoint.Y = System.Windows.Forms.Cursor.Position.Y - this.Top;
mouseDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
this.Left = System.Windows.Forms.Cursor.Position.X - diffPoint.X;
this.Top = System.Windows.Forms.Cursor.Position.Y - diffPoint.Y;
}
}
This works, tested.