Closed theitdejan closed 5 years ago
@Desomph I need 2 things... can you create a short sample with your Behavior in there and second, can you try latest source (self compiled)? Thx.
@punker76 Sorry for so much code, but I've added it because I believe there's another issue: I cannot drop on top of items that are nested in Canvas, in this case: GroupBox. If you need an actually short sample, I'll try mashing up one a bit later. Don't wanna waste your time. I've added some labels for you to see. I've rebuilt the dll's from the source, and referenced the newly built ones in my project. Everything is done through the MVVM.
Note I forgot: I'm using Canvas within a SimpleChildWindow, your other project. https://github.com/punker76/MahApps.Metro.SimpleChildWindow
Here's a short gif/video preview: https://gfycat.com/ImaginaryMajesticBarnswallow
So here's the behavior class:
public class CanvasMouseBehaviour : System.Windows.Interactivity.Behavior<Canvas>
{
public static readonly DependencyProperty MouseYProperty = DependencyProperty.Register(
"MouseY", typeof(double), typeof(CanvasMouseBehaviour), new PropertyMetadata(default(double)));
public double MouseY
{
get { return (double)GetValue(MouseYProperty); }
set { SetValue(MouseYProperty, value); }
}
public static readonly DependencyProperty MouseXProperty = DependencyProperty.Register(
"MouseX", typeof(double), typeof(CanvasMouseBehaviour), new PropertyMetadata(default(double)));
public double MouseX
{
get { return (double)GetValue(MouseXProperty); }
set { SetValue(MouseXProperty, value); }
}
protected override void OnAttached()
{
AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;
}
private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
var pos = mouseEventArgs.GetPosition(AssociatedObject);
MouseX = pos.X;
MouseY = pos.Y;
}
protected override void OnDetaching()
{
AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;
}
}
Here's the SimpleChildWindow view (important part) :
<ItemsControl ItemsSource="{Binding DcCanvasFields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas
dd:DragDrop.DropHandler="{Binding FlowScreenCreationCanvasDragDrop}"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
Background="Wheat">
<i:Interaction.Behaviors>
<behaviours:CanvasMouseBehaviour MouseX="{Binding InnerMouseX, Mode=OneWayToSource}" MouseY="{Binding InnerMouseY, Mode=OneWayToSource}" />
</i:Interaction.Behaviors>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ReSharper disable Xaml.BindingWithContextNotResolved -->
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
<!-- ReSharper restore Xaml.BindingWithContextNotResolved -->
<ItemsControl.ItemTemplateSelector>
<customControl:FlowScreenFieldTemplateSelector>
<!-- GROUP BOX TEMPLATE -->
<customControl:FlowScreenFieldTemplateSelector.GroupBoxTemplate>
<DataTemplate>
<GroupBox
Width="{Binding Width}"
Height="{Binding Height}"
d:DataContext="{d:DesignInstance Type=dataCollection1:DcCanvasFlowScreenField,
IsDesignTimeCreatable=False}"
dd:DragDrop.DropHandler="{Binding DataContext.FlowScreenCreationGroupBoxDragDrop, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
Background="{DynamicResource WhiteBrush}"
Header="{Binding Label}">
<Label Content="{Binding Label}" />
</GroupBox>
</DataTemplate>
</customControl:FlowScreenFieldTemplateSelector.GroupBoxTemplate>
<!-- REGULAR FIELD TEMPLATE -->
<customControl:FlowScreenFieldTemplateSelector.FieldTemplate>
<DataTemplate />
</customControl:FlowScreenFieldTemplateSelector.FieldTemplate>
</customControl:FlowScreenFieldTemplateSelector>
</ItemsControl.ItemTemplateSelector>
</ItemsControl>
DropHandler is bound to this property in ViewModel:
public FlowScreenCreationCanvasDragDrop FlowScreenCreationCanvasDragDrop { get; set; }
And at the end, I've implemented IDropTarget, which calls ViewModel for the drop implementation:
public class FlowScreenCreationCanvasDragDrop : IDropTarget
{
private DataCollectionViewModel Base { get; set; }
public FlowScreenCreationCanvasDragDrop(DataCollectionViewModel baseref)
{
Base = baseref;
}
public void DragOver(IDropInfo dropInfo)
{
dropInfo.DropTargetAdorner = typeof(DropTargetHighlightAdorner);
dropInfo.Effects = DragDropEffects.Move;
}
public void Drop(IDropInfo dropInfo)
{
Base.FlowScreenCanvasDropFn(dropInfo);
}
}
@Desomph Did you tried to use PreviewMouseMove at the CanvasMouseBehaviour instead normal one?
@punker76 I just tried swapping between PreviewMouseMove and MouseMove, on separate canvas and it still didn't work. Which is weird, because I remember it working at first, but nothing changed on my code part.
@Desomph I'll try to find out what's the problem is...
@punker76 Thanks a lot! Let me know if you come up with a solution so I can stop hacking things.
@Desomph Sorry to keep you waiting so long, but I need more info or better a simple sample app where I can debug this issue. With the latest alpha you can now set which events shouls be used #300
What steps will reproduce this issue?
I've written a custom CanvasMouseBehavior, which implements Interactivity.Behavior
I've tried adding
AllowDrop=True
but it changed nothing.IDropTarget is implemented in separate class CanvasDragDrop which is referenced in ViewModel :
public CanvasDragDrop CanvasDragDrop { get; set; }
Expected outcome
MouseOver should be properly detected even when dragging items over Canvas.
Repo
https://github.com/punker76/gong-wpf-dragdrop
Environment