C# WPF -Drag an image

2019-04-11 16:38发布

问题:

I am trying to get some simple functionality of getting an image from a file, adding it to a Canvas, and then allowing a user to left-click (and hold) on the image and then drag it around the Canvas (i.e. updating the image's location)

Here's what I have so far, what should I be adding?

private void btnAddImage_Click(object sender, RoutedEventArgs e) {
    try {
        System.Windows.Forms.OpenFileDialog open = new System.Windows.Forms.OpenFileDialog();
        open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
        if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
            PictureBox PictureBox1 = new PictureBox();
            PictureBox1.Image = new Bitmap(open.FileName);
            myCanvas.children.add(PictureBox1);
        }
    }
    catch (Exception) { throw new ApplicationException("Failed loading image"); }
}

回答1:

You may add an Image control to the Canvas and modify its Left and Top properties on mouse input.

XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Canvas x:Name="canvas"
            MouseLeftButtonDown="CanvasMouseLeftButtonDown"
            MouseLeftButtonUp="CanvasMouseLeftButtonUp"
            MouseMove="CanvasMouseMove"/>
    <Button Grid.Row="1" Content="Add Image" Click="AddButtonClick"/>
</Grid>

Code behind:

private void AddButtonClick(object sender, RoutedEventArgs e)
{
    var dialog = new Microsoft.Win32.OpenFileDialog();
    dialog.Filter =
        "Image Files (*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";

    if ((bool)dialog.ShowDialog())
    {
        var bitmap = new BitmapImage(new Uri(dialog.FileName));
        var image = new Image { Source = bitmap };
        Canvas.SetLeft(image, 0);
        Canvas.SetTop(image, 0);
        canvas.Children.Add(image);
    }
}

private Image draggedImage;
private Point mousePosition;

private void CanvasMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var image = e.Source as Image;

    if (image != null && canvas.CaptureMouse())
    {
        mousePosition = e.GetPosition(canvas);
        draggedImage = image;
        Panel.SetZIndex(draggedImage, 1); // in case of multiple images
    }
}

private void CanvasMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (draggedImage != null)
    {
        canvas.ReleaseMouseCapture();
        Panel.SetZIndex(draggedImage, 0);
        draggedImage = null;
    }
}

private void CanvasMouseMove(object sender, MouseEventArgs e)
{
    if (draggedImage != null)
    {
        var position = e.GetPosition(canvas);
        var offset = position - mousePosition;
        mousePosition = position;
        Canvas.SetLeft(draggedImage, Canvas.GetLeft(draggedImage) + offset.X);
        Canvas.SetTop(draggedImage, Canvas.GetTop(draggedImage) + offset.Y);
    }
}


回答2:

You need to add drag and drop support in your code, by handling drag and drop routed events in the WPF controls you use.

If you use .NET 4.0 and above (Visual Studio 2010 and above), please see this MSDN Library of WPF Drag and Drop Overview.

But please take note on what kind of data that is being dragged and dropped as well.