WPFのinkCanvasで手書きでなく直線や円の描画方法

タグの編集
投稿者 質問  (学生) 投稿日時 2010/2/1 18:39:43
VB2008とXAMLでinkCanvasを使って簡単に手書き描画は行えましたが、
直線や円や四角などをマウスダウンからアップに合わしたinkCanvas上の描画方法が分かりません。
お分かりの方おられましたら、参考になるサイトや記述方法など教えていただけないでしょうか?
よろしくお願いいたします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/2/2 05:21:35
> マウスダウンからアップに合わしたinkCanvas上の描画方法が分かりません。
スタイラスペンではなく、マウスを使って操作しているのですね。

であれば、こんな感じでいかがでしょう。

Private Sub Window1_Loaded( _
  ByVal sender As Object, _
  ByVal e As System.Windows.RoutedEventArgs _
  ) Handles Me.Loaded
    inkCanvas1.EditingMode = InkCanvasEditingMode.None
End Sub

Private mouseSpc As StylusPointCollection

Private Sub inkCanvas1_MouseDown( _
  ByVal sender As System.Object, _
  ByVal e As System.Windows.Input.MouseButtonEventArgs _
  ) Handles inkCanvas1.MouseDown
    mouseSpc = New StylusPointCollection()
    Dim p As Point = e.GetPosition(inkCanvas1)
    mouseSpc.Add(New StylusPoint(p.X, p.Y))
End Sub

Private Sub inkCanvas1_MouseUp( _
  ByVal sender As Object, _
  ByVal e As System.Windows.Input.MouseButtonEventArgs _
  ) Handles inkCanvas1.MouseUp
    If mouseSpc IsNot Nothing Then
        Dim p As Point = e.GetPosition(inkCanvas1)
        mouseSpc.Add(New StylusPoint(p.X, p.Y))
        inkCanvas1.Strokes.Add(New System.Windows.Ink.Stroke(mouseSpc))
        mouseSpc = Nothing
    End If
End Sub

投稿者 質問  (学生) 投稿日時 2010/2/2 18:59:02
魔界の仮面弁士さん
ご回答ありがとうございます。
大変参考になりました。

円や四角などはどのようにすればよいでしょうか?
又、マウスアップで描画されるのではなく、マウスの軌跡を追いながら直線、円、四角を描画する
ことを最終的に実現したいと思いますが、MouseMoveにご回答頂いた記述を入れてみて試行錯誤
していますが、マウスの軌跡にそった描画になり直線になってくれません。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/2/2 23:17:26
多角形を描く際には、描き始めの点に戻るように座標を指定してみてください。
たとえば、
Dim p As New StylusPointCollection()
p.Add(New StylusPoint(10, 10))
p.Add(New StylusPoint(70, 10))
p.Add(New StylusPoint(70, 70))
p.Add(New StylusPoint(10, 10))
InkCanvas1.Strokes.Add(New System.Windows.Ink.Stroke(p))
にすれば、直角二等辺三角形になります。


あるいは、ストロークとして描くのではなく、
System.Windows.Shapes 名前空間で用意された図形を用いる方法もあります。
http://msdn.microsoft.com/ja-jp/library/system.windows.shapes.aspx


> マウスの軌跡を追いながら直線、円、四角を描画する
MouseMove 中で、描画データを変化させていけばよいかと思います。

たとえば、塗りつぶし楕円を描くならこんな感じ。
今回は、上記の System.Windows.Shapes 名前空間を用いています。
Private Sub Window1_Loaded(ByVal sender As Object, _
    ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    InkCanvas1.EditingMode = InkCanvasEditingMode.None
End Sub

Private ellipse As Ellipse
Private LeftTop As Point

Private Sub InkCanvas1_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Input.MouseButtonEventArgs _
    ) Handles InkCanvas1.MouseDown
    ellipse = New Ellipse()
    LeftTop = e.GetPosition(InkCanvas1)
    ellipse.SetValue(InkCanvas.LeftProperty, LeftTop.X)
    ellipse.SetValue(InkCanvas.TopProperty, LeftTop.Y)
    ellipse.Width = 1.0#
    ellipse.Height = 1.0#
    ellipse.Fill = New SolidColorBrush(Colors.Blue)
    InkCanvas1.Children.Add(ellipse)
End Sub

Private Sub InkCanvas1_MouseMove(ByVal sender As Object, _
    ByVal e As System.Windows.Input.MouseEventArgs _
    ) Handles InkCanvas1.MouseMove
    If ellipse IsNot Nothing Then
        Dim p As Point = e.GetPosition(InkCanvas1)
        Dim w As Double = p.X - LeftTop.X
        Dim h As Double = p.Y - LeftTop.Y
        ellipse.Width = If(w <= 0.1#, 0.1#, w)
        ellipse.Height = If(h <= 0.1#, 0.1#, h)
    End If
End Sub

Private Sub InkCanvas1_MouseUp(ByVal sender As Object, _
    ByVal e As System.Windows.Input.MouseButtonEventArgs _
    ) Handles InkCanvas1.MouseUp
    If ellipse IsNot Nothing Then
        ellipse = Nothing
    End If
End Sub