Drag canvas on relative panel

Shay Wilner 1,746 Reputation points
2020-06-24T16:59:44.717+00:00

Hi

I try to apply a game to place 8 queens on a chess board
I have a relative panel named boardgame and inside a relative panel named gamearea that is the chess board and also 8 canvas named
queen1 to queens10

Now i try to move a queen on the board, the problem is not only to drag and drop ,i want to show while dragging the threatened lines from the another queens
<RelativePanel x:Name ="Boardgame" RelativePanel.Below="Stripoption" RelativePanel.AlignHorizontalCenterWithPanel="True"
Margin="20,20,0,0" CornerRadius="6,6,6,6" Width="{x:Bind Path= classsize.widthboard }" Height="{x:Bind Path= classsize.heightboard }"
BorderThickness="6,6,6,6">

            <Canvas x:Name="gamearea" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignTopWithPanel = "True"  
                AllowDrop="True"     Margin="20,20,0,0" >  
            </Canvas>  
            <Canvas x:Name ="queen" RelativePanel.RightOf="gamearea" RelativePanel.AlignTopWith="gamearea" CanDrag="True"  
                    Width="29" Height="66" Background="Azure">  
                <Image  Source ="/Assets/queen.png "   
                   Stretch="None" Margin="2,6,0,0" >  
                </Image>  
            </Canvas>  
              
        </RelativePanel>  
    </RelativePanel>  

How can i get the position of a queen relative to the gamearea (chessboard) to check if the row or column or diagonal are threatened
something like this i wrote as form application project
10509-screenshot-18.png

Thanks

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Daniele 1,996 Reputation points
    2020-06-25T06:21:55.067+00:00

    Using drag and drop event handlers you can do like that:

       <Canvas x:Name="gamearea" AllowDrop="True" Width="400" Height="400"  
               DragOver="Gamearea_OnDragOver" DragEnter="Gamearea_OnDragEnter">  
           <Canvas.Background>  
               <ImageBrush ImageSource="/Assets/chessboard.jpg" />  
           </Canvas.Background>  
           <Image Source="/Assets/queen.png" CanDrag="True" Width="50" Height="50"  
                  Stretch="Fill" DragStarting="Image_OnDragStarting"  
                  Canvas.Top="100" Canvas.Left="150"/>  
           <Image Source="/Assets/queen.png" CanDrag="True" Width="50" Height="50"  
                  Stretch="Fill" DragStarting="Image_OnDragStarting"  
                  Canvas.Top="250" Canvas.Left="50"/>  
           <Image Source="/Assets/queen.png" CanDrag="True" Width="50" Height="50"  
                  Stretch="Fill" DragStarting="Image_OnDragStarting"  
                  Canvas.Top="300" Canvas.Left="250"/>  
       </Canvas>  
    
    
    
       private void Image_OnDragStarting(UIElement sender, DragStartingEventArgs args)  
       {  
           args.Data.Properties.Add("chessman", sender);  
       }  
         
       private void Gamearea_OnDragEnter(object sender, DragEventArgs e)  
       {  
           e.DragUIOverride.IsCaptionVisible = false;  
           e.AcceptedOperation = DataPackageOperation.None;  
       }  
         
       private void Gamearea_OnDragOver(object sender, DragEventArgs e)  
       {  
           var canvas = (Canvas) sender;  
           DataPackageView dataPackageView = e.DataView;  
           var chessman = (Image) dataPackageView.Properties["chessman"];  
             
           (int x, int y)[] others = gamearea.Children.Where(c => c != chessman).Select(i => (GetCoordinates(canvas, i))).ToArray();  
         
           (int x, int y) chessmanPoint = GetCoordinates(canvas, e.GetPosition(gamearea));  
         
           foreach ((int x, int y) other in others)  
           {  
               if (other.x == chessmanPoint.x || other.y == chessmanPoint.y || Math.Abs(other.x - chessmanPoint.x) == Math.Abs(other.y - chessmanPoint.y))   
               {  
                   e.AcceptedOperation = DataPackageOperation.None;  
                   return;  
               }  
         
               e.AcceptedOperation = DataPackageOperation.Move;  
           }  
       }  
         
       private static (int x, int y) GetCoordinates(Canvas canvas, Point point)  
       {  
           return GetCoordinates(canvas, point.X, point.Y);  
       }  
         
       private static (int x, int y) GetCoordinates(Canvas canvas, UIElement uiElement)  
       {  
           double top = Canvas.GetTop(uiElement);  
           double left = Canvas.GetLeft(uiElement);  
         
           return GetCoordinates(canvas, left, top);  
       }  
         
       private static (int x, int y) GetCoordinates(Canvas canvas, double left, double top)  
       {  
           double cellWidth = canvas.ActualWidth / 8;  
           double cellHeight = canvas.ActualHeight / 8;  
         
           var x = (int) Math.Floor(left / cellWidth);  
           var y = (int) Math.Floor(top / cellHeight);  
         
           return (x, y);  
       }  
    

    10655-chess.gif

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Roy Li - MSFT 33,366 Reputation points Microsoft Vendor
    2020-06-25T03:20:02.573+00:00

    Hello,

    Welcome to Microsoft Q&A!

    How can i get the position of a queen relative to the gamearea (chessboard) to check if the row or column or diagonal are threatened

    To get the position of the queen, you could handle the PointerMoved Event of the gamearea canvas. You could get the position of the cursor when you drag the queen.

    Like this:

     public MainPage()  
            {  
                this.InitializeComponent();  
                TargetCanvas.PointerMoved += TargetCanvas_PointerMoved;  
            }  
      
            private void TargetCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)  
            {  
                var x = e.GetCurrentPoint(TargetCanvas).Position.X;  
                var y = e.GetCurrentPoint(TargetCanvas).Position.Y;  
      
                Debug.WriteLine("X = " + x );  
                Debug.WriteLine("Y = " + y );  
            }  
    

    Thank you.

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.