Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polygon automatcally adjust to its above polygon

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.

enter image description here

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

  1. I'm using Canvas.setTop because without setting it my polygon show over the first.
  2. 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.

enter image description here

like image 930
Sunny Bhadana Avatar asked Apr 06 '18 01:04

Sunny Bhadana


2 Answers

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);
}
like image 114
Gaurang Dave Avatar answered Oct 22 '22 08:10

Gaurang Dave


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;
    }
like image 1
GCamel Avatar answered Oct 22 '22 06:10

GCamel