タッチで領域指定した時のエリア選択枠を動かす (C#+3行)
#wp7dev_jp #wpdev_jp
前回、タッチで領域指定した時のエリア選択枠を描く で、タッチ&ドラッグで矩形を表示する処理を実装しました。
矩形描画処理の考え方
処理的には、タッチしたら、その場所に矩形を移動させ、ドラッグしたらその移動量だけ大きさを変える感じです。何もない状態から行うので、画像と矩形を取りまとめる、Grid でイベント処理を受けています。
矩形移動処理の考え方
こんどは、描画した矩形を動かします。この場合は、移動量に合わせて矩形の位置を変更するだけです。やり方はいろいろありますが、この場合は矩形でイベントを受けて移動処理をしてみます。
重なったオブジェクトそれぞれでイベントを受ける時の注意
ただ、こういった処理方法をした場合、注意が必要です。というのも、矩形でイベントを受けて処理をしても、その下のGridにもイベント処理は伝わってしまうのです。イベントは、そこに重なっているオブジェクトすべてに伝播します。これをイベントバブリングと呼びます。すると、せっかく移動処理のために矩形を触っても、その後Gridを触ったことにもなってしまい、その瞬間矩形の描画処理が始まってしまいます。
ですから、矩形でイベントを受けた時は、そのあとイベントバブリングが起こらないよう、イベントの発生を手なければなりません。
UIの実装
大きな違いは、Image と同じサイズのGridでまとめている点、Rectangle で2つのイベントを受けている点ですね。
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid Background="Transparent"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ManipulationStarted="ContentPanel_ManipulationStarted"
ManipulationDelta="ContentPanel_ManipulationDelta">
<Image Stretch="Uniform" Source="/App001;component/cat.jpg" />
<Rectangle Name="rectangle1" Visibility="Collapsed"
HorizontalAlignment="Left" VerticalAlignment="Top"
StrokeDashArray="2,2" Stroke="Yellow" StrokeThickness="3"
Fill="#20000000"
ManipulationDelta="rectangle1_ManipulationDelta"
ManipulationStarted="rectangle1_ManipulationStarted" />
</Grid>
</Grid>
C#
まずは、前回と同じ矩形作成のための処理。前回と同じです。
private void ContentPanel_ManipulationStarted(
object sender, ManipulationStartedEventArgs e)
{
rectangle1.Margin = new Thickness(
e.ManipulationOrigin.X, e.ManipulationOrigin.Y, 0, 0);
rectangle1.Width = 0;
rectangle1.Height = 0;
rectangle1.Visibility = System.Windows.Visibility.Visible;
}
private void ContentPanel_ManipulationDelta(
object sender, ManipulationDeltaEventArgs e)
{
rectangle1.Width = e.CumulativeManipulation.Translation.X;
rectangle1.Height = e.CumulativeManipulation.Translation.Y;
}
続けて、矩形自体をタッチした時の処理。処理は何もしませんが、矩形の移動モードになるので、e.Handled =true として、Grid にイベントが伝わらないようにしています。
private void rectangle1_ManipulationStarted(
object sender, ManipulationStartedEventArgs e)
{
e.Handled = true;
}
そして、矩形上でドラッグした時の処理。矩形の位置をドラッグした移動量分だけ動かしています。ここも、そのままではGrid側で同じイベントが起きてしまうので、ここでも、e.Handled =true として、Grid にイベントが伝わらないようにしています。
private void rectangle1_ManipulationDelta(
object sender, ManipulationDeltaEventArgs e)
{
rectangle1.Margin = new Thickness(
rectangle1.Margin.Left + e.DeltaManipulation.Translation.X,
rectangle1.Margin.Top + e.DeltaManipulation.Translation.Y,
0, 0);
e.Handled = true;
}
実行
タッチ&ドラッグで作成。さらに矩形のタッチ&ドラッグで矩形を移動させることが出来ます。
関連情報