我在 Windows 8 商店应用程序的 StackPanel 中有一个可拖动元素。我的目标很简单:将项目拖动到屏幕上的某个位置,在用户停止拖动后,元素应立即返回到其原始起始位置。
我有以下代码来完成这项任务:
private void grdCover_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
Grid coverControl = sender as Grid;
double xOffset = -e.Cumulative.Translation.X;
double yOffset = -e.Cumulative.Translation.Y;
if (coverControl.RenderTransform is TranslateTransform)
{
TranslateTransform existingTransform = coverControl.RenderTransform as TranslateTransform;
existingTransform.X += xOffset;
existingTransform.Y += yOffset;
}
else
{
TranslateTransform transform = new TranslateTransform();
transform.X = xOffset;
transform.Y = yOffset;
coverControl.RenderTransform = transform;
}
}
代码类型的作品。应用程序启动时屏幕如下所示:
看起来像 H 的顶部元素与看起来像 U 的底部元素很好地对齐。当我第一次拖动 H 元素时,它会跳回其良好对齐的位置,或者至少任何未对齐的地方都非常小以至于几乎无法察觉到肉眼。当我不断拖动和释放 H 元素时,它变得越来越错位,如下所示:
在 15-20 次拖动移动后,H 元素完全放错了位置:
问题可能是由于 Point 对象中的 double 值在转换为像素时的一些舍入误差,但这只是一个疯狂的猜测。此外,在高分辨率设备(例如我的 PC)上,与在较低分辨率设备(例如 Visual Studio 中的 Windows 模拟器)上相比,需要更多的移动才能使错位变得可见。
可能与此问题相关的其他一些代码:
我使用以下代码执行拖动操作:
private void Grid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
TranslateTransform translateTransform = (sender as Grid).RenderTransform as TranslateTransform;
translateTransform.X += e.Delta.Translation.X;
translateTransform.Y += e.Delta.Translation.Y;
}
在用户完成拖动元素后,我还有以下事件处理程序来阻止元素在屏幕上移动太多:
private void grdCover_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingRoutedEventArgs e)
{
e.TranslationBehavior.DesiredDeceleration = 10000000000000000;
e.Handled = true;
}
如果您想知道我想将所需的减速度设置为 Double.Max 以阻止屏幕上任何进一步的“滑动”运动,但我得到一个例外,说它超出了界限。所以我选择了这个任意大的值。
我在布局根或要移动的元素或其容器上没有额外的边距或填充。
欢迎任何想法。
谢谢, 安德拉斯