WPF handles drag and drop and left click

I'm having trouble getting DragDrop.DoDragDrop to work well with the left-click event.

My control has several links that you can either drag or left-click to visit.

I am currently subscribing to a mouse mouse preview event in which I fire a drag event if the left mouse button is clicked.

In another callback, I handle left-click and up to check the click. Is there anyway to check if DragDrop really had a drag event?

+4
source share
2 answers

See this link drag and drop to wpf explained at the end and scroll down a bit to the "Drag and Drop Detection" section

The encase blog code entered here disappears ...

From [ http://msdn2.microsoft.com/en-us/library/aa289508(vs.71).aspx] Here is the sequence of events in a typical drag and drop operation:

Dragging is initiated by calling the DoDragDrop method on the source control.

The DoDragDrop method takes two parameters: data indicating data for the transfer of allowed permissions, indicating which operations (copying and / or moving) are allowed

A new DataObject is created. This, in turn, raises the GiveFeedback event. In most cases, you don’t need to worry about the GiveFeedback event, but if you want to display a custom mouse cursor while dragging, you can add your code.

Any control with the AllowDrop property set to True is a potential target point. The AllowDrop property can be set in the Properties window at design time or programmatically in the Form_Load event.

When the mouse passes through each control, the DragEnter event for that control is raised. The GetDataPresent method is used to ensure that the data format matches the target control, and the Effect property is used to display the corresponding mouse pointer.

If the user releases the mouse button over a valid target, the DragDrop event will be raised. The code in the DragDrop event handler retrieves data from the DataObject and displays it in the target control.

Drag and drop detection

Before calling DoDragDrop, we need to detect a drag operation on the source ... The mouse move is usually MouseLeftButtonDown + MouseMove (before the MouseLeftButton rises).

So, our drag and drop control needs to subscribe to these two events:

 void Window1_Loaded(object sender, RoutedEventArgs e) { this.DragSource.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DragSource_PreviewMouseLeftButtonDown); this.DragSource.PreviewMouseMove += new MouseEventHandler(DragSource_PreviewMouseMove); } 

To prevent a false drag and drop operation from starting when the user accidentally drags, you can use

SystemParameters.MinimumHorizontalDragDistance and SystemParameters.MinimumVerticalDragDistance

One way to do this is on MouseLeftButtonDown, write down the starting position and onMouseMove check if the mouse is moved enough.

 void DragSource_PreviewMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed && !IsDragging) { Point position = e.GetPosition(null); if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance) { StartDrag(e); } } } void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { _startPoint = e.GetPosition(null); } 

Drag it .. now what?

Data! You need to find out what is under the mouse when dragging. I will skip, make a simple exit, and suppose that the one who runs MouseMove is what I want to drag. Take a look at MouseEventArgs.OriginalSource .. [or you can do 2D HitTesting with VisualTreeHelper .. In Part 3, this entry will try to lead you through a hit checking list, which is another common scenario I come across.

When you have a drag object, you will need to pack what you send to the DataObject, which describes the data that you are viewing. DataObject is a wrapper that displays shared data (identified with extensible formats) for drag and drop. If the source and destination understand the format, you will be set. Thus, DataObject has several interesting methods:

SetData (type format, object data) /// format is the "format" of the day you go through (for example, Formats.Text, Formats.Image, etc.), you can pass any custom types.

GetDataPresent (type type) /// is what the target will use to request and retrieve data. If it is a type that it can handle, it will call GetData () and process it.

There is not much interesting here. In the sample, I just hardcoded my data like string ... this makes it easier to paste into external containers (like Word, which you can use to check this part of the record). I need to emphasize that the drag and drop must be related to the data ... Providing visual feedback during the drag and drop operation.

Before we call DoDragDrop (), we have several “options” for creating the feedback we want to provide, and the “areas” d & d.

Do we want the user cursor to be displayed during the execution of the Drag operation? If we need a cursor, what should it be?

How far do we want to drag? in the application or through Windows applications?

The simplest scenario: there is no custom cursor, and we want it to drag and drop applications:

If you don't want a fancy cursor, you're done! You can directly call DoDragDrop ...

 private void StartDrag(MouseEventArgs e) { IsDragging = true; DataObject data = new DataObject(System.Windows.DataFormats.Text.ToString(), "abcd"); DragDropEffects de = DragDrop.DoDragDrop(this.DragSource, data, DragDropEffects.Move); IsDragging = false; } 

Note: this code allows you to drag and drop various processes, uses the default feedback of the operating system (for example, + for copying).

+13
source

there is Drag Over / Enter / Leave Attached events you can subscribe to these (or one) events on your draggable UIElement element and see if the drag is in progress.

0
source

Source: https://habr.com/ru/post/1438671/


All Articles