Freigeben über


タッチで領域指定した時のエリア選択枠を動かす (C#+3行)

#wp7dev_jp #wpdev_jp

前回、タッチで領域指定した時のエリア選択枠を描く で、タッチ&ドラッグで矩形を表示する処理を実装しました。

矩形描画処理の考え方

処理的には、タッチしたら、その場所に矩形を移動させ、ドラッグしたらその移動量だけ大きさを変える感じです。何もない状態から行うので、画像と矩形を取りまとめる、Grid でイベント処理を受けています。

image

矩形移動処理の考え方

こんどは、描画した矩形を動かします。この場合は、移動量に合わせて矩形の位置を変更するだけです。やり方はいろいろありますが、この場合は矩形でイベントを受けて移動処理をしてみます。

image

重なったオブジェクトそれぞれでイベントを受ける時の注意

ただ、こういった処理方法をした場合、注意が必要です。というのも、矩形でイベントを受けて処理をしても、その下のGridにもイベント処理は伝わってしまうのです。イベントは、そこに重なっているオブジェクトすべてに伝播します。これをイベントバブリングと呼びます。すると、せっかく移動処理のために矩形を触っても、その後Gridを触ったことにもなってしまい、その瞬間矩形の描画処理が始まってしまいます。

image

ですから、矩形でイベントを受けた時は、そのあとイベントバブリングが起こらないよう、イベントの発生を手なければなりません。

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;
}

 

実行

タッチ&ドラッグで作成。さらに矩形のタッチ&ドラッグで矩形を移動させることが出来ます。

imageimage

関連情報

  1. タッチで領域指定した時のエリア選択枠を描く (XAML 1行、C#6行)
  2. タッチで領域指定した時のエリア選択枠を動かす (C#+3行)
  3. タッチで領域指定したエリア選択枠で写真を切り出す(XAML2行+C#6行)