26

在我的应用程序中,用户可以选择 anImage并将其拖到 a 上Grid,以使用它。我通过PointerEntered处理Grid. 在这里,我检测用户是否选择了图像以及用户是否按住鼠标按钮。

现在我想将 放置Image在网格上,并将(仍然按下的)指针传递给 my Image,因此Image使用它自己的ManipulationStartedManipulationDelta事件ManipulationCompleted。这应该让用户将图像从图像列表平滑地拖动到Grid,而不必释放并单击元素。

我尝试从senderin释放指针PointerEntered,并使用捕获它CapturePointer,但这似乎不起作用,即使CapturePointer返回true

这是我用于PointerEntered事件的代码:

private void DrawingArea_OnPointerEntered(object sender, PointerRoutedEventArgs e)
{
    // If we enter the grid while dragging and we have an image that was dragged
    if (e.Pointer.IsInContact && CurrentDraggedImage != null)
    {
        DrawingArea.Children.Add(CurrentDraggedImage);

        // Move it to the location we're currently at
        var transform = (CurrentDraggedImage.RenderTransform as CompositeTransform);
        transform.TranslateX += e.GetCurrentPoint(DrawingArea).RawPosition.X - DrawingArea.ActualWidth / 2;
        transform.TranslateY += e.GetCurrentPoint(DrawingArea).RawPosition.Y - DrawingArea.ActualHeight/2;

        // This works (I think)
        (sender as UIElement).ReleasePointerCaptures();
        // This doesn't work (or it isn't what I need), but returns true
        CurrentDraggedImage.CapturePointer(e.Pointer);

        // Get ready for a new image
        CurrentDraggedImage = null;
    }
}

我的操作代码在这个答案中:

https://stackoverflow.com/a/32230733/1009013

4

1 回答 1

0

你为什么不直接使用拖放?创建一个包含工具栏的网格(例如要拖动的图像列表)和响应拖放命令的目标网格:

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <ListBox Background="AliceBlue" MouseMove="OnMouseMove">

        <ListBox.Resources>
            <Style TargetType="{x:Type Image}">
                <Setter Property="Width" Value="64" />
                <Setter Property="Height" Value="64" />
            </Style>
        </ListBox.Resources>

        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_pawn_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_rook_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_knight_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_bishop_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_queen_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_king_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_pawn_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_rook_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_knight_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_bishop_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_queen_T.png" />
        <Image Source="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_king_T.png" />
    </ListBox>

    <GridSplitter Grid.Column="1" Width="5" Background="LightGray" />

    <Grid x:Name="targetGrid" Grid.Column="2" AllowDrop="True" DragEnter="OnDragEnter" DragOver="OnDragMove" DragLeave="OnDragLeave" Drop="OnDrop" Background="Transparent"/>

</Grid>

您的列表框需要一个 MouseMove 处理程序来检测何时拖动图像,并且您的命令处理程序只需根据需要响应各种事件,克隆所需图像并将它们相应地拖动到网格表面:

public partial class MainWindow : Window
{
    private Image DragImage = null;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        // make sure we have an image
        var image = e.OriginalSource as Image;
        if (image == null)
            return;

        // make sure we've started dragging
        if (e.LeftButton != MouseButtonState.Pressed)
            return;

        DragDrop.DoDragDrop(image, image, DragDropEffects.Copy);
    }

    private void OnDragEnter(object sender, DragEventArgs e)
    {
        // make sure we have an image
        if (!e.Data.GetDataPresent(typeof(Image)))          
        {
            e.Effects = DragDropEffects.None;
            return;
        }

        // clone the image
        var image = e.Data.GetData(typeof(Image)) as Image;
        e.Effects = DragDropEffects.Copy;
        this.DragImage = new Image { Source = image.Source, Width=64, Height=64 };
        var position = e.GetPosition(this.targetGrid);
        this.DragImage.SetValue(Grid.MarginProperty, new Thickness(position.X-32, position.Y-32, 0, 0));
        this.DragImage.SetValue(Grid.HorizontalAlignmentProperty, HorizontalAlignment.Left);
        this.DragImage.SetValue(Grid.VerticalAlignmentProperty, VerticalAlignment.Top);
        this.DragImage.IsHitTestVisible = false; // so we don't try and drop it on itself

        // add it to the target grid
        targetGrid.Children.Add(this.DragImage);
    }

    private void OnDragMove(object sender, DragEventArgs e)
    {
        var position = e.GetPosition(this.targetGrid);
        this.DragImage.SetValue(Grid.MarginProperty, new Thickness(position.X - 32, position.Y - 32, 0, 0));
    }

    private void OnDragLeave(object sender, DragEventArgs e)
    {
        targetGrid.Children.Remove(this.DragImage);
        this.DragImage = null;
    }


    private void OnDrop(object sender, DragEventArgs e)
    {
        this.DragImage.IsHitTestVisible = true;
        this.DragImage = null;
    }

}

结果:

在此处输入图像描述

我在这里用可怕而丑陋的 WPF 方式做事,而不是干净优雅的 MVVM,但你明白了。我也不明白你为什么要在网格而不是画布周围拖动东西?

于 2015-09-09T05:12:36.453 回答