Reputation: 1071
i used a drag adorner to clone the image of my labels ( drag target ) but however now i couldn't drop my label into my textbox ,
this is the code i have used ( u might see theres previewdragover , i wrote e.Handled = true in previewdragover but doesn't help ) i have also set tbox.AllowDrop to true :
TextBox :
tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop);
tbox.PreviewDragOver += new DragEventHandler(tbox_PreviewDragOver);
Handlers for textbox :
protected void tbox_PreviewDrop(object sender, DragEventArgs e)
{
(sender as TextBox).Text = string.Empty; // Empty the textbox from previous answer.
(sender as TextBox).Background = Brushes.White;
e.Handled = true;
}
Label ( drag target ) :
Label lbl = new Label();
lbl.Content = s;
lbl.Width = Double.NaN;
lbl.Height = 40;
lbl.FontSize = 19;
lbl.MouseDown += new MouseButtonEventHandler(lbl_MouseDown);
lbl.MouseMove += new MouseEventHandler(lbl_MouseMove);
lbl.GiveFeedback += new GiveFeedbackEventHandler(lbl_GiveFeedback);
lbl.MouseUp += new MouseButtonEventHandler(lbl_MouseUp);
wrapPanel2.Children.Add(lbl);
Handlers for label :
private void lbl_MouseUp(object sender, MouseButtonEventArgs e)
{
Mouse.OverrideCursor = Cursors.Arrow;
}
private void lbl_MouseDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(this);
}
private void lbl_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var source = sender as UIElement;
Label lbl = sender as Label;
Point current = e.GetPosition(this);
Vector diff = startPoint - current;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
adorner = new DragAdorner(lbl, e.GetPosition(lbl));
AdornerLayer.GetAdornerLayer(lbl).Add(adorner);
var dragData = new DataObject(this);
DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy);
AdornerLayer.GetAdornerLayer(lbl).Remove(adorner);
}
startPoint = current;
}
}
private void lbl_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (adorner != null)
{
Label lbl = sender as Label;
var pos = lbl.PointFromScreen(GetMousePosition());
adorner.UpdatePosition(pos);
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
public static Point GetMousePosition()
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
private Point startPoint;
private DragAdorner adorner;
Now i can drag the labels with the labels following my cursor but i can't drop them in any textbox.
-----EDIT------------
I have put a dragenter for textbox like this :
private void tbox_PreviewDragEnter(object sender, DragEventArgs e)
{
if (sender == e.Source)
{
e.Effects = DragDropEffects.None;
}
}
Still not working tho.
i'll add the DragAdorner.cs here that i've used ( i got it from some chinese web ) :
public class DragAdorner : Adorner {
public DragAdorner(UIElement adornedElement, Point offset)
: base(adornedElement) {
this.offset = offset;
vbrush = new VisualBrush(AdornedElement);
vbrush.Opacity = .7;
}
public void UpdatePosition(Point location) {
this.location = location;
this.InvalidateVisual();
}
protected override void OnRender(DrawingContext dc) {
var p = location;
p.Offset(-offset.X, -offset.Y);
dc.DrawRectangle(vbrush, null, new Rect(p, this.RenderSize));
}
private Brush vbrush;
private Point location;
private Point offset;
Upvotes: 5
Views: 11391
Reputation: 41
The problem is that your drag adorner is always on top. When you try to drop your label it drops on the adorner instead of the underlying component.
To avoid this add the following line to the constructor of the DragAdorner.
IsHitTestVisible = false;
Upvotes: 4
Reputation: 1
Initialize your Dragadorner with Point(-5,-5). (new DragAdorner(new Point(-5,-5));)
The drop Event seems to be thrown on the Adorner. If you add a drop handler to the Adorner youll see that it gets called when you release the mouse.
It seems that the Mouse pointer is over the Adorner and it takes it as Target.
Setting the offset to a Point so that the Adorner is not under the Mousepointer corrects that behavior.
Upvotes: 0
Reputation: 69959
Your code is somewhat different to my working example, but I think that I can see your problem. In my code, I have a method called UpdateDragDropEffects
. This method takes in an object of type DragEventArgs
named e
and updates the e.Effects
property dependent on the value of the e.AllowedEffects
property and also whether I have a valid ICommand
instance to call and whether the data is of the expected type, etc.
This method is called (and the DragEventArgs
object passed from) two typical drag and drop methods; DragTargetPreviewDrop
(handles the PreviewDrop
event) and AdornedUIElementPreviewDragOver
(handles the PreviewDragOver
event). Setting the e.Effects
property of the DragEventArgs
object tells the system whether the current drag opearation is valid and should continue or not... not setting it, or setting it to DragDropEffects.None
will have the effect of not displaying any valid drop targets.
The Drag and Drop Overview page at MSDN has code examples that should also help you. The Enabling an Element to be a Drop Target
section has example code that shows what I have described.
You could also have other problems, but come back and update if this doesn't help you.
Upvotes: 0