I'm making a Windows Desktop Application that have drag and drop functionality. I'm using Polygon (And Images later) Shapes for drag and drop. The drag and drop functionality works fine but I want that if user drag any shape from the panel and when he drag other shape then the second shape automatically fix with first shape. You'll understand it by take a look at below screenshots.
It is the Screen Shot of what happens when I drag Shapes
When user drop the polygon near the other polygon it will automatically adjust itself, if the same polygon drop in other area of canvas than a error will show to the user.
Here is my XAML Code
<Window x:Class="Images.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Images" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <DockPanel VerticalAlignment="Stretch" Height="Auto"> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" MinWidth="400" Margin="10"> <GroupBox DockPanel.Dock="Left" Width="350" Background="Aqua" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Height="Auto"> <WrapPanel Margin="0,10,0,0" VerticalAlignment="Top"> <Button Name="control" Content="Control" Height="30" Background="BlueViolet" Margin="5" Width="100"/> <Button Name="motion" Content="Motion" Width="100" Margin="5" Background="Green" Height="30"/> <Button Name="variable" Content="Variable" Width="100" Margin="5" Background="SeaGreen" Height="30"/> <Button Name="sensor" Content="Sensor" Width="100" Margin="5" Background="OrangeRed" Height="30"/> <Button Name="lcd" Content="LCD" Width="100" Margin="5" Height="30" Background="PaleVioletRed"/> <Button Name="function" Content="Function" Width="100" Margin="5" Height="30" Background="Salmon"/> <StackPanel Name="heaading" Width="350"> <TextBlock Name="controlName" TextAlignment="Center" Text="Controls"/> </StackPanel> <StackPanel Name="userControls" Orientation="Vertical"> <!-- Users Controls Items Goes Here --> <Polygon Name="startProgram" Points="80,10, 80, 80, 135,80, 135, 45, 205, 45, 205, 80, 260, 80, 260,10" Fill="Chocolate" Stroke="Black" StrokeThickness="2" MouseLeftButtonDown="shape_MouseLeftButtonDown" /> <Polygon Name="endProgram" Fill="BlueViolet" Points="80,40, 80,80, 260,80, 260,40, 200,40, 200,10, 140,10,140,40" Stroke="Black" StrokeThickness="2" MouseLeftButtonDown="shape_MouseLeftButtonDown" /> </StackPanel> </WrapPanel> </GroupBox> <!-- Change this to Canvas for work later --> <Canvas x:Name="dropArea" DockPanel.Dock="Right" Margin="10" Background="#FF9760BF" Width="Auto" HorizontalAlignment="Stretch" AllowDrop="True" Drop="dropArea_Drop"> </Canvas> </DockPanel> </DockPanel> </Window>
Here is my CS code
namespace Images { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void dropArea_Drop(object sender, DragEventArgs e) { var shape = e.Data.GetData(typeof(Polygon)) as Polygon; Console.WriteLine("Polygon Name : " + shape.Name); Polygon myPolygon = new Polygon(); myPolygon.Stroke = shape.Stroke; myPolygon.Fill = shape.Fill; myPolygon.StrokeThickness = 2; Canvas.SetTop(myPolygon, e.GetPosition(dropArea).Y); myPolygon.Points = shape.Points; dropArea.Children.Add(myPolygon); myPolygon.MouseRightButtonDown += new MouseButtonEventHandler(dragged_ShapeMouseDown); } private void dragged_ShapeMouseDown(object sender, MouseButtonEventArgs e) { //Show Options to Delete or set Value to current Polygon } private void shape_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Polygon shape = e.Source as Polygon; DragDrop.DoDragDrop(shape, shape, DragDropEffects.Copy); } } }
Problem
- I'm using Canvas.setTop because without setting it my polygon show over the first.
- Here I'm setting the polygon that fix with its above polygon but it can be left or right also as shown in below screenshot.
2 Answers
Answers 1
SOLUTION
For Deleting shape
myPolygon.MouseLeftButtonUp += new MouseButtonEventHandler(dragged_ShapeMouseDown); private void dragged_ShapeMouseDown(object sender, MouseButtonEventArgs e) { if (dropArea.Children.Count > 0) dropArea.Children.Remove(sender as Polygon); }
Answers 2
Sacha Barber has got very nice article that describe exactly what you are trying to do i think...4 steps articles up to MVVM ! have a look these step1 and step2, step3, step4 - I also used it in my own project ArchX
well, i think everything is there in my code : during onmove test the result and change the cursor. ondragend : use a HitHelper to determine where you release the mouse and return the shape his tested - then adjust the shape of the polygon regarding the hit result : below sample code - GuideLineManager
public Cursor HitTestGuide(Point p, RulerOrientation mode) { if (_Guides.Exists(g => (int)g.Info.Orientation == (int)mode && g.HitTest(p))) { return _Guides.First(g => (int)g.Info.Orientation == (int)mode && g.HitTest(p)).Cursor; } return Cursors.Arrow; }
and the onDragEnd, call to get the hit tested object
public Guideline GetSnapGuide(Point hitPoint) { foreach (Guideline gl in Guides) { if (!gl.IsDisplayed) continue; if (gl.Info.IsSnap && !gl.Info.IsMoving) if (gl.IsOnGuide(hitPoint, _Container.dPicCapture)) { return gl; } } return null; }
0 comments:
Post a Comment