[英]How can I make my Rectangle react to touch events like it does for mouse/pointer events?
在我的MainPage上,我有一个充满彩色矩形的Stackpanel,它们都以Margin设置为(0,5,0,5)开头。 我想允许用户仅水平移动这些矩形。 由于矩形没有鼠标事件,因此我使用了指针来实现这一点。 流程是:用户点击一个Rectangle来选择它,更改光标以提供视觉提示,用户向左或向右拖动Rectangle。 (请注意,Stackpanel确实有一个垂直滚动查看器)。 这是我的C#代码:
private void Rectangle_FirstClick(object sender, EventArgs e)
{
// Give rectangle a white border to imply selection
Rectangle myControl = sender as Rectangle;
myControl.StrokeThickness = 1;
myControl.Stroke = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240));
// Provide visual cue to mouse users by changing the pointer immediately
Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 0);
// Handle mouse leaving/re-entering the track piece
myControl.PointerEntered += MyControl_PointerEntered;
myControl.PointerExited += MyControl_PointerExited;
// Handle the drag event
myControl.PointerPressed += MyControl_PointerPressed;
myControl.PointerReleased += MyControl_PointerReleased;
myControl.PointerMoved += MyControl_PointerMoved;
}
以下是各个事件处理程序
bool PossibleDragStart = false;
Point InitialDragPoint = new Point(0, 0);
private void MyControl_PointerExited(object sender, PointerRoutedEventArgs e)
{
Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 0);
}
private void MyControl_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 0);
}
private void MyControl_PointerPressed(object sender, PointerRoutedEventArgs e)
{
PossibleDragStart = true;
InitialDragPoint = e.GetCurrentPoint(sender as Rectangle).Position;
}
private void MyControl_PointerReleased(object sender, PointerRoutedEventArgs e)
{
PossibleDragStart = false;
}
private void MyControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
// If pointer pressed without release, and then moved, we are dragging
if (PossibleDragStart)
{
Point CurrentDragPoint = e.GetCurrentPoint(AudioTracksRightContainer).Position;
StatusBar.Text = CurrentDragPoint.X.ToString();
// Calculate drag offset by subtracting Current Position from Initial Position
double SegmentMargin = CurrentDragPoint.X - InitialDragPoint.X;
// Move the Rectangle with the pointer drag
Rectangle trackSegment = sender as Rectangle;
trackSegment.Margin = new Thickness(SegmentMargin, 5, 0, 5);
}
}
该代码非常适合鼠标使用,但是当我尝试使用它进行触摸时,我必须按住以启动拖动,即使那样,矩形在放置前也只移动了几个单位。 我不确定为什么行为会有所不同。
此代码的另一个问题是,如果矩形足够窄,以至于当我快速拖动并且矩形无法跟上光标时,当光标离开矩形边界时,它将停止拖动。 比触摸无法解决的问题小得多,但仍然有点烦人。
听起来好像ScrollViewer正在捕获触摸事件以进行自己的滚动。 您可以使用Xaml的操纵引擎来注册操纵事件,以手动操纵操纵。 这不仅更容易编码,而且效率更高。 默认情况下,它将适用于触摸和鼠标。
<Rectangle Margin="5" Fill="Orange" Height="100" Width="200"
ManipulationMode="TranslateX"
ManipulationDelta="Rectangle_ManipulationDelta"
>
<Rectangle.RenderTransform>
<CompositeTransform />
</Rectangle.RenderTransform>
</Rectangle>
在Rectangle_ManipulationDelta方法中,转换矩形:
private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
UIElement elem = sender as UIElement;
CompositeTransform ct = elem.RenderTransform as CompositeTransform;
ct.TranslateX += e.Delta.Translation.X;
}
如果只需要平移,则可以使用TranslateTransform而不是CompositeTransform,或者可以添加旋转和缩放。
有关使用手势和操纵事件的更多信息,请参见快速入门:触摸输入(XAML) 。
我在博客条目中讨论了ScrollViewer接管指针处理的问题我所有的手势都去了哪里? 如果您真的想自己处理指针事件,我将讨论如何在拖动过程中禁用ScrollViewer。 您可以通过捕获指针来处理手指移动快于目标的情况。 如果您处理操作事件,则不需要此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.