Подтвердить что ты не робот

Пусть указатель захвата изображения ManipulationMode

В моем приложении пользователь может выбрать Image и перетащить его на Grid, чтобы играть с ним. Я делаю это, обрабатывая событие PointerEntered Grid. Здесь я обнаруживаю, что пользователь выбрал изображение, и если пользователь удерживает кнопку мыши.

Теперь я хочу поместить Image в сетку и передать указатель (все еще нажатый) на мой Image, поэтому Image использует свои собственные ManipulationStarted, ManipulationDelta и ManipulationCompleted события. Это должно позволить пользователю перетаскивать изображение одним плавным движением из списка изображений в Grid, вместо того, чтобы отпускать и нажимать на элемент.

Я попытался высвободить указатель из sender в 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;
    }
}

В этом ответе содержится мой код манипуляции:

qaru.site/info/416494/...

4b9b3361

Ответ 1

Почему бы вам просто не использовать drag-n-drop? Создайте сетку, содержащую вашу панель инструментов (например, список перетаскиваемых изображений) и целевую сетку, которая отвечает на команды dragdrop:

<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, но вы поняли эту идею. Я также не понимаю, почему вы хотите перетаскивать вещи вокруг Grid вместо Canvas?