private void MainGrid_MouseDown(object sender, MouseButtonEventArgs e) { previousMousePosition = e.GetPosition(mainGrid); // Reverse-transform mouse grid coordinates (screen) into Canvas coordinates Matrix m = mainMatrixTransform.Matrix; m.Invert(); var mouseT = m.Transform(previousMousePosition); pmm = null; isMovingMode = false; foreach (var gsSource in b.AllStacks()) { movingGroup = gsSource.FromHitTest(mouseT); if (movingGroup != null) { Point P1 = movingGroup.GetTopLeft(); StartingPoint = P1; Vector v = P1 - mouseT; // A closure to be executed my MouseMoveWhenDown with mouse coordinates (in game space) as parameter P pmm = P => { movingGroup.SetTopLeft(P + v); movingGroup.ToStack = null; // Reset in case mouse is moving away from a potential drop target foreach (var gsTarget in b.AllStacks()) { if (gsTarget != movingGroup.FromStack) { if (gsTarget.ToHitTest(P, movingGroup)) { movingGroup.ToStack = gsTarget; } } } }; // Be sure to call GetPosition before Capture, otherwise GetPosition returns 0 after Capture // Capture to get MouseUp event raised by grid Mouse.Capture(mainGrid); mainGrid.MouseMove -= new MouseEventHandler(MainGrid_MouseMoveWhenUp); mainGrid.MouseMove += new MouseEventHandler(MainGrid_MouseMoveWhenDown); return; } } // Clicked outside active and valid area movingGroup = null; }