2014-02-17 185 views
4

我试图谷歌如何使画布上的UIElements拖放&,但找不到任何我想要的东西。C#拖放画布内的图像

我有一个窗口的C#WPF应用程序。在窗口内部,我得到了一个Canvas,我可以在其中添加图像。 我想要的是能够拖动&放置图像,同时停留在画布边框内。 我也希望这是代码,所以不在xaml。

我在添加/更新图像到画布的功能中得到了这个。 TODO's应该替换为Drag & Drop事件。注:虽然这是为了以后,如果有人有代码一次拖放多个图像作为额外的奖金,我将不胜感激。

在此先感谢您的帮助。

+0

与其编辑您的问题,您为什么不将解决方案作为答案发布并接受它?它以这种方式与网站的其他部分保持一致。 – Joe

回答

4

时间固定项目我下面的问题,通过下面的代码:

img.AllowDrop = true; 
img.PreviewMouseLeftButtonDown += this.MouseLeftButtonDown; 
img.PreviewMouseMove += this.MouseMove; 
img.PreviewMouseLeftButtonUp += this.PreviewMouseLeftButtonUp; 


private object movingObject; 
private double firstXPos, firstYPos; 
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { 
    // In this event, we get the current mouse position on the control to use it in the MouseMove event. 
    Image img = sender as Image; 
    Canvas canvas = img.Parent as Canvas; 

    firstXPos = e.GetPosition(img).X; 
    firstYPos = e.GetPosition(img).Y; 

    movingObject = sender; 

    // Put the image currently being dragged on top of the others 
    int top = Canvas.GetZIndex(img); 
    foreach (Image child in canvas.Children) 
     if (top < Canvas.GetZIndex(child)) 
      top = Canvas.GetZIndex(child); 
    Canvas.SetZIndex(img, top + 1); 
} 
private void PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { 
    Image img = sender as Image; 
    Canvas canvas = img.Parent as Canvas; 

    movingObject = null; 

    // Put the image currently being dragged on top of the others 
    int top = Canvas.GetZIndex(img); 
    foreach (Image child in canvas.Children) 
     if (top > Canvas.GetZIndex(child)) 
      top = Canvas.GetZIndex(child); 
    Canvas.SetZIndex(img, top + 1); 
} 
private void MouseMove(object sender, MouseEventArgs e) { 
    if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject) { 
     Image img = sender as Image; 
     Canvas canvas = img.Parent as Canvas; 

     double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left; 
     // newLeft inside canvas right-border? 
     if (newLeft > canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth) 
      newLeft = canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth; 
     // newLeft inside canvas left-border? 
     else if (newLeft < canvas.Margin.Left) 
      newLeft = canvas.Margin.Left; 
     img.SetValue(Canvas.LeftProperty, newLeft); 

     double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top; 
     // newTop inside canvas bottom-border? 
     if (newTop > canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight) 
      newTop = canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight; 
     // newTop inside canvas top-border? 
     else if (newTop < canvas.Margin.Top) 
      newTop = canvas.Margin.Top; 
     img.SetValue(Canvas.TopProperty, newTop); 
    } 
} 

此代码让我可以拖动和删除画布中的图像,而无需离开画布本身。

现在我只需要能够做两两件事:

  1. 修正了一个小错误在我的形象的鼠标滑动时,我拖累他们身边快速。这种情况经常发生,即使我甚至没有快速移动拖动图像时也是如此。Fixed by using the solution mentioned in my other question.
  2. 使其能够一次拖放多个图像,最好先选择多个图像,在Canvas内停留时将它们全部放下。

会为此提出新的问题。

+0

复制和粘贴,它只是工作。代码很容易遵循,点击之间没有奇怪的位置返回。 – KMC

+0

@KMC不要忘记添加来自[这个答案](http://stackoverflow.com/questions/21857929/c-sharp-drag-drop-multiple-images-within-canvas)的代码来修复bug请注意第一点。 –

+0

@KevinCruijssen我不明白为什么(在MouseMove处理程序中)您使用Canvas.Margin评估新位置(包括X和Y)。它只有在删除所有这些后才有效! – Brutus

0

我没有使用你的代码的块并做拖放在画布上,查看一下,看看有没有什么区别,真的没有检查

private void pinCanvas_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e) 
     { 
     // Point pt = e.GetPosition(pinCanvas); 
     // Curosor.Text = String.Format("You are at ({0}in, {1}in) in window coordinates", (pt.X/(96/72)) * 1/72, (pt.Y/(96/72)) * 1/72); 
     } 
     bool captured = false; 
     double x_shape, x_canvas, y_shape, y_canvas; 
     UIElement source = null; 
     string elementName; 
     double elementHeight, elementWidth; 
     private void pinCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      setCanvasSize(); 
      source = (UIElement)sender; 
      elementName = ((Label)source).Name; 
      switch (elementName) 
      { 
       case "pinTextBox" : 
        elementHeight = pinActualHeight; 
        elementWidth = pinActualWidth; 
        break; 
       case "serialTextBox" : 
        elementHeight = serialActualHeight; 
        elementWidth = serialActualWidth; 
        break; 
       case "batchTextBox" : 
        elementHeight = batchActualHeight; 
        elementWidth = batchActualWidth; 
        break; 
      } 
      Mouse.Capture(source); 
      captured = true; 
      x_shape = Canvas.GetLeft(source); 
      x_canvas = e.GetPosition(Maincanvas).X; 
      y_shape = Canvas.GetTop(source); 
      y_canvas = e.GetPosition(Maincanvas).Y; 
     } 

     private void pinCanvas_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (captured) 
      { 

       double x = e.GetPosition(Maincanvas).X; 
       double y = e.GetPosition(Maincanvas).Y; 
       var xCond = Math.Round(appActivities.DIP2Inch(x_shape), 4).ToString(); 
       var yCond = Math.Round(appActivities.DIP2Inch(y_shape), 4).ToString(); 
       var name = ((Label)source).Name; 
       x_shape += x - x_canvas; 
      // if ((x_shape < Maincanvas.ActualWidth - elementWidth) && x_shape > 0) 
      //  { 
        Canvas.SetLeft(source, x_shape); 
        switch (name) 
        { 
         case "pinTextBox" : 
          pinOffsetLeft.Text = xCond; 
          break; 
         case "serialTextBox" : 
          serialOffsetLeft.Text = xCond; 
          break; 
         case "batchTextBox" : 
          batchOffsetLeft.Text = xCond; 
          break; 
        } 

     //  } 
       x_canvas = x; 
       y_shape += y - y_canvas; 
      // if (y_shape < Maincanvas.ActualHeight - elementHeight && y_shape > 0) 
      // { 
        Canvas.SetTop(source, y_shape); 
        switch (name) 
        { 
         case "pinTextBox": 
          pinOffsetTop.Text = yCond; 
          break; 
         case "serialTextBox": 
          serialOffsetTop.Text = yCond; 
          break; 
         case "batchTextBox": 
          batchOffsetTop.Text = yCond; 
          break; 
        } 

      //  } 
       y_canvas = y; 
      } 
     } 

     private void pinCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      Mouse.Capture(null); 
      captured = false; 
      // MessageBox.Show((Canvas.GetTop(source)).ToString()); 
     /* if (Canvas.GetTop(source) < 0) 
      { 
       Canvas.SetTop(source, 0); 
      } 
      if (Canvas.GetLeft(source) < 0) 
      { 
       Canvas.SetLeft(source, 0); 
      } 

      if (Canvas.GetLeft(source) > Maincanvas.ActualWidth - elementWidth) 
      { 
       // MessageBox.Show("Left Too Much " + (Canvas.GetLeft(source) * 1/96).ToString()); 
       Canvas.SetLeft(source, Maincanvas.ActualWidth - elementWidth); 
      } 

      if (Canvas.GetTop(source) > Maincanvas.ActualHeight - elementHeight) 
      { 
       Canvas.SetTop(source, Maincanvas.ActualHeight - elementHeight); 
      } */ 
      oneElemntTorched = true; 
      //MessageBox.Show(this.pinTextBox.ActualHeight.ToString() + ", " + this.pinTextBox.ActualWidth.ToString()); 
     }