Surface 用の WPF アプリケーションを開発していますが、私も同僚も答えがわからないバグに遭遇しました。
ユーザーがボックスから物をドラッグできる状況があります。ボックスは単なる画像であり、それに触れると、別の画像が生成され、ドラッグ アンド ドロップなどの操作を行うオブジェクトになります。ドラッグ全体は で実行されSurfaceDragDrop.BeginDragDrop(...)
ます。ドロップすると、オブジェクトは単純に消えます。
ここでの問題は、ときどき (入力が急速に来て、実際にオブジェクトをドラッグせずに画面を叩くだけのようです)、スポーンされたアイテムが決してデスポーンしないことです。つまり、入力が削除されても画面に残ります。タッチしてドラッグし続けることで操作できますが、別の指が既に操作していると思われるため、移動と回転はオフになっています。
ただし、デバッグを通じて、オブジェクトにタッチが登録されていないことを確認しました。そのAreAnyTouchesCaptured
プロパティはfalse
です。ただし、操作はアクティブです。何が起こっているように見えるかというと、終わりのないある種の操作に入るということです。それを取り除くために、SurfaceDragDrop.CancelDragDrop(..)
タッチがキャプチャされずに一定期間画面に表示されていたオブジェクトに対して単純に行う一時的な解決策を実装しました。
問題の説明がある程度明確であることを願っています。そうでない場合は、質問してください。以下は、オブジェクトをスポーンするために使用されるコードです。ただし、私はそれを書いていません(元同僚が書きました)。デバッグに固執しています:
private void item_PreviewTouchDown(object sender, TouchEventArgs e)
{
var box = sender as Canvas;
var imgpath = String.Format(@"[someimgpath].png");
var bmp = new BitmapImage(new Uri(imgpath, UriKind.RelativeOrAbsolute));
Image draggedItem = new Image { Source = bmp, Stretch = Stretch.None, Width = bmp.Width, Height = bmp.Height };
draggedItem.UpdateLayout();
var touchPoint = e.TouchDevice.GetTouchPoint(box);
var itemX = touchPoint.Position.X - draggedItem.Width / 2.0;
var itemY = touchPoint.Position.Y - draggedItem.Height / 2.0;
box.Children.Add(draggedItem);
draggedItem.SetValue(Canvas.LeftProperty, itemX);
draggedItem.SetValue(Canvas.TopProperty, itemY);
draggedItem.Visibility = System.Windows.Visibility.Hidden;
//We should perfom drag-and-drop when the size of the draggedItem is updated, since
//BeginDragDrop uses ActualWidth and ActualHeight property
draggedItem.SizeChanged += (o, ev) =>
{
List<InputDevice> devices = new List<InputDevice>();
devices.Add(e.TouchDevice);
foreach (TouchDevice touch in box.TouchesCapturedWithin)
{
if (touch != e.TouchDevice)
{
devices.Add(touch);
}
}
var img = new Image { Source = draggedItem.Source, Stretch = Stretch.None, Width = bmp.Width, Height = bmp.Height };
img.SetValue(Canvas.LeftProperty, itemX);
img.SetValue(Canvas.TopProperty, itemY);
var cursor = SurfaceDragDrop.BeginDragDrop(box, draggedItem, img, draggedItem, devices, DragDropEffects.Move);
};
e.Handled = true;
}