让图像处理模式捕获指针

Let image ManipulationMode capture pointer

提问人:vrwim 提问时间:8/27/2015 最后编辑:Communityvrwim 更新时间:5/2/2023 访问量:1106

问:

在我的应用程序中,用户可以选择一个并将其拖动到 上来玩它。我通过处理 .在这里,我检测用户是否选择了图像,以及用户是否按住鼠标按钮。ImageGridPointerEnteredGrid

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

我尝试从 in 中释放指针并使用 捕获它,但这似乎不起作用,即使返回 .senderPointerEnteredCapturePointerCapturePointertrue

以下是我用于该事件的代码: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

C# win-universal-app rendertransform

评论

0赞 Justin XL 9/2/2015
您是否考虑过不同的方法 - 使用 ListView 中的内置 CanDragItems 并在绘图区域上将 AllowDrop 设置为 true?
0赞 vrwim 9/2/2015
@JustinXL 没有,但我想这给了同样的障碍......我会检查一下并回复您。
0赞 vrwim 9/7/2015
@JustinXL是的,同样的问题,无法将指针从一个拖放动作移动到另一个......

答:

0赞 Mark Feldman 9/9/2015 #1

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

<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 处理程序来检测何时拖动图像,命令处理程序只需根据需要响应各种事件,克隆 require 图像并相应地将它们拖动到网格的表面上:

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;
    }

}

结果:

enter image description here

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

评论

0赞 vrwim 5/10/2016
我现在才回到这个问题,我现在将尝试以文明的方式使拖放工作(目前是点击添加)。我记得使用网格是因为我不了解 Canvas,而且大多数其他元素似乎都不是正确的选择,或者不允许多个子元素。
0赞 vrwim 5/12/2016
我现在已经使用拖放实现了它,UWP 似乎没有 ,所以我需要使用 .此外,捕获方式在 UWP 上不起作用,因为 ListView 会捕获该内容以滚动(应用程序位于平板电脑上)。DragDrop.DoDragDropCanDragItemsOnMouseMove