提问人:vrwim 提问时间:8/27/2015 最后编辑:Communityvrwim 更新时间:5/2/2023 访问量:1106
让图像处理模式捕获指针
Let image ManipulationMode capture pointer
问:
在我的应用程序中,用户可以选择一个并将其拖动到 上来玩它。我通过处理 .在这里,我检测用户是否选择了图像,以及用户是否按住鼠标按钮。Image
Grid
PointerEntered
Grid
现在我想将 放在网格上,并将(仍然按下的)指针传递给我的 ,因此使用自己的 和事件。这应该允许用户将图像从图像列表平滑地拖动到 ,而不必释放并单击元素。Image
Image
Image
ManipulationStarted
ManipulationDelta
ManipulationCompleted
Grid
我尝试从 in 中释放指针并使用 捕获它,但这似乎不起作用,即使返回 .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;
}
}
我的操作代码在这个答案中:
答:
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;
}
}
结果:
我在这里用可怕和丑陋的 WPF 方式做事,而不是干净优雅的 MVVM,但你明白了。我也不明白为什么你想在网格而不是画布上拖动东西?
评论
0赞
vrwim
5/10/2016
我现在才回到这个问题,我现在将尝试以文明的方式使拖放工作(目前是点击添加)。我记得使用网格是因为我不了解 Canvas,而且大多数其他元素似乎都不是正确的选择,或者不允许多个子元素。
0赞
vrwim
5/12/2016
我现在已经使用拖放实现了它,UWP 似乎没有 ,所以我需要使用 .此外,捕获方式在 UWP 上不起作用,因为 ListView 会捕获该内容以滚动(应用程序位于平板电脑上)。DragDrop.DoDragDrop
CanDragItems
OnMouseMove
评论