Kontakt-Formular   Inhaltsverzeichnis   Druckansicht  

VisualBasic.tips

Startseite > VisualBasic.Net > Unterschriften auch für WinForms

Unterschriften auch für WinForms

Mit der Maus sieht es gruselig aus, mit dem Stift geht es bestimmt besser....

 

Download Beispielprojekt VS2013

Unterschriften für Winforms-Anwendungen? Es braucht dazu keine Third-Party-Tools oder teure Hardware. Alles was man dazu braucht ist eine PictureBox.

Schritt 1: Benutzersteuerelment dem Projekt hinzufügen

In diesem Beispiel nenne ich das Steuerelement: InkSignUserControl

Abbildung 1: Neues Benutzersteuerlement hinzufügen

Abbildung 1: Neues Benutzersteuerlement hinzufügen

 

Schritt 2: Steuerelement designen

Auf diesem Formular verwende ich folgende Steuerelemente

  • ein "TableLayoutPanel"
  • ein "Button"
  • und eine "PictureBox"
Abbildung 2: Design des Benutzersteuerelements

Abbildung 2: Design des Benutzersteuerelements 

Öffnen Sie den Designer und ersetzen sie den kompletten Code mit dem Code aus Listing 1.

Abbildung 3: Designer-Code anzeigen lassen

Abbildung 3: Designer-Code anzeigen lassen

 

Listing 1: "Designer-Code" des Benutzersteuerelementes "InkSignUserControl"
 <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class InkSignUserControl
   Inherits System.Windows.Forms.UserControl

   'UserControl überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
   <System.Diagnostics.DebuggerNonUserCode()> _
   Protected Overrides Sub Dispose(ByVal disposing As Boolean)
      Try
         If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
         End If
      Finally
         MyBase.Dispose(disposing)
      End Try
   End Sub

   'Wird vom Windows Form-Designer benötigt.
   Private components As System.ComponentModel.IContainer

   'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
   'Das Bearbeiten ist mit dem Windows Form-Designer möglich.  
   'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
   <System.Diagnostics.DebuggerStepThrough()> _
   Private Sub InitializeComponent()
      Me.TableLayoutPanel = New System.Windows.Forms.TableLayoutPanel()
      Me.InkPanel = New System.Windows.Forms.PictureBox()
      Me.CommandReset = New System.Windows.Forms.Button()
      Me.TableLayoutPanel.SuspendLayout()
      CType(Me.InkPanel, System.ComponentModel.ISupportInitialize).BeginInit()
      Me.SuspendLayout()
      '
      'TableLayoutPanel
      '
      Me.TableLayoutPanel.AutoSize = True
      Me.TableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
      Me.TableLayoutPanel.ColumnCount = 5
      Me.TableLayoutPanel.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
      Me.TableLayoutPanel.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
      Me.TableLayoutPanel.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
      Me.TableLayoutPanel.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
      Me.TableLayoutPanel.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
      Me.TableLayoutPanel.Controls.Add(Me.InkPanel, 1, 1)
      Me.TableLayoutPanel.Controls.Add(Me.CommandReset, 3, 2)
      Me.TableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill
      Me.TableLayoutPanel.Location = New System.Drawing.Point(0, 0)
      Me.TableLayoutPanel.Name = "TableLayoutPanel"
      Me.TableLayoutPanel.RowCount = 4
      Me.TableLayoutPanel.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
      Me.TableLayoutPanel.RowStyles.Add(New System.Windows.Forms.RowStyle())
      Me.TableLayoutPanel.RowStyles.Add(New System.Windows.Forms.RowStyle())
      Me.TableLayoutPanel.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
      Me.TableLayoutPanel.Size = New System.Drawing.Size(586, 464)
      Me.TableLayoutPanel.TabIndex = 2
      '
      'InkPanel
      '
      Me.InkPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
      Me.TableLayoutPanel.SetColumnSpan(Me.InkPanel, 3)
      Me.InkPanel.Location = New System.Drawing.Point(23, 119)
      Me.InkPanel.Name = "InkPanel"
      Me.InkPanel.Size = New System.Drawing.Size(540, 180)
      Me.InkPanel.TabIndex = 4
      Me.InkPanel.TabStop = False
      '
      'CommandReset
      '
      Me.CommandReset.Location = New System.Drawing.Point(413, 305)
      Me.CommandReset.Name = "CommandReset"
      Me.CommandReset.Size = New System.Drawing.Size(150, 40)
      Me.CommandReset.TabIndex = 6
      Me.CommandReset.Tag = ""
      Me.CommandReset.Text = "Zurücksetzen"
      Me.CommandReset.UseVisualStyleBackColor = True
      '
      'InkSignUserControl
      '
      Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
      Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
      Me.Controls.Add(Me.TableLayoutPanel)
      Me.Name = "InkSignUserControl"
      Me.Size = New System.Drawing.Size(586, 464)
      Me.TableLayoutPanel.ResumeLayout(False)
      CType(Me.InkPanel, System.ComponentModel.ISupportInitialize).EndInit()
      Me.ResumeLayout(False)
      Me.PerformLayout()

   End Sub
   Private WithEvents TableLayoutPanel As System.Windows.Forms.TableLayoutPanel
   Private WithEvents InkPanel As System.Windows.Forms.PictureBox
   Private WithEvents CommandReset As System.Windows.Forms.Button

End Class
Schritt 3: "CodeBehind"

Anschliessend kopieren die den "CodeBehind" aus Listing 2.

Abbildung 4: "CodeBehind" anzeigen und durch Listing 2 ersetzen

Abbildung 4: "Code Behind" anzeigen

 

Listing 2: "Code Behind" des Benutzersteuerelementes "InkSignUserControl"
#Region "Imports"
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Runtime.Serialization
#End Region


<Serializable> _
Public Class InkSignUserControl

#Region "Enums"

   Enum ImageStateEnum
      Empty
      Init
      Load
   End Enum

#End Region

#Region "Event"

   Public ValueChangedEventHandler As EventHandler(Of InkSignChangedEventArgs)

   Public Custom Event ValueChanged As EventHandler(Of InkSignChangedEventArgs)
      AddHandler(ByVal value As EventHandler(Of InkSignChangedEventArgs))
         ValueChangedEventHandler = CType(System.Delegate.Combine(ValueChangedEventHandler, value),  _
                                       EventHandler(Of InkSignChangedEventArgs))
      End AddHandler
      RemoveHandler(ByVal value As EventHandler(Of InkSignChangedEventArgs))
         ValueChangedEventHandler = CType(System.Delegate.Remove(ValueChangedEventHandler, value),  _
                                       EventHandler(Of InkSignChangedEventArgs))
      End RemoveHandler
      RaiseEvent(ByVal sender As Object, ByVal e As InkSignChangedEventArgs)
         If Not sender Is Nothing Then
         End If
      End RaiseEvent
   End Event

   Protected Overridable Sub TriggerChangeEvent()
      Dim localHandler As EventHandler(Of InkSignChangedEventArgs) = ValueChangedEventHandler
      If Not localHandler Is Nothing Then
         localHandler(Me, New InkSignChangedEventArgs(Me))
      End If
   End Sub

#End Region

#Region "Members"

   Private DrawingMode As Boolean = False
   Private bmp As Bitmap = Nothing
   Private Plist As List(Of Point)
   Private PenColor As Color = Color.Black
   Private NewPen As Pen

   Private _ImageState As ImageStateEnum = ImageStateEnum.Empty
   Public Property ImageState() As ImageStateEnum
      Get
         Return _ImageState
      End Get
      Set(ByVal value As ImageStateEnum)
         If _ImageState.Equals(value) = False Then
            _ImageState = value
            ChangeState()
         End If
      End Set
   End Property

   Private InterruptEvents As Boolean = False

   Private _Value As String = ""
   Public Property Value() As String
      Get
         Return _Value
      End Get
      Set(ByVal value As String)
         If _Value.Equals(value) = False Then
            _Value = value
            TriggerChangeEvent()
         End If
      End Set
   End Property

#End Region

#Region "Constructors"

   Public Sub New()
      Dim res As Integer = 0

      Try

         Me.InitializeComponent()

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

#End Region

#Region "Functions"

   Public _
      Function ChangeState _
      ( _
      ) _
      As Integer
      Dim res As Integer = 0

      Try

         Select Case ImageState
            Case ImageStateEnum.Empty
               CommandReset.Visible = False
            Case ImageStateEnum.Init
               CommandReset.Visible = True
            Case ImageStateEnum.Load
               CommandReset.Visible = True
         End Select

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      Finally
         InterruptEvents = False
      End Try

      Return res
   End Function

   Public _
      Function SetValue _
      ( _
         ByVal Value As String _
      ) _
      As Integer
      Dim res As Integer = 0

      Try

         _Value = Value
         ImageLoad()

      Catch ex As Exception
         res = -1
         '* TODO: Ausnahmebehandlung
      End Try

      Return res
   End Function


   Public _
      Function ImageReset _
      ( _
      ) _
      As Integer
      Dim res As Integer = 0

      Try

         '* Neues Hintergrundbild erstellen
         bmp = New Bitmap(InkPanel.Width, InkPanel.Height)
         '* Hintergrund weiss füllen
         Using gr = Graphics.FromImage(bmp)
            gr.FillRectangle(Brushes.White, 0, 0, InkPanel.Width, InkPanel.Height)
         End Using

         '* Neues Hintergrundbild ablegen
         InkPanel.Image = bmp

         Plist = New List(Of Point)
         Me.DoubleBuffered = True

         ImageState = ImageStateEnum.Init

      Catch ex As Exception
         res = -1
         '* TODO: Ausnahmebehandlung
      End Try

      Return res
   End Function

   Public _
      Function ImageSave _
      ( _
      ) _
      As Integer
      Dim res As Integer = 0

      Try

         Dim img As Image = Image.FromHbitmap(CType(InkPanel.Image, Bitmap).GetHbitmap)
         Dim stm As MemoryStream = New MemoryStream
         img.Save(stm, Imaging.ImageFormat.Png)

         Dim fileArray() As Byte = stm.ToArray()

         Value = System.Convert.ToBase64String( _
                                 fileArray, _
                                 0, _
                                 fileArray.Length)

         ImageState = ImageStateEnum.Load

      Catch ex As Exception
         res = -1
         '* TODO: Ausnahmebehandlung
      End Try

      Return res
   End Function

   Public _
      Function ImageLoad _
      ( _
      ) _
      As Integer
      Dim res As Integer = 0

      Try

         If _Value.Length = 0 Then
            Exit Try
         End If

         '* Base64-String in Byte-Array umwandeln
         Dim myBytes() As Byte = Nothing
         myBytes = System.Convert.FromBase64String(_Value)

         '* Byte-Array in Stream einlesen
         Dim OutputStream As System.IO.MemoryStream = Nothing
         OutputStream = New System.IO.MemoryStream(myBytes)

         Dim img As Image = Image.FromStream(OutputStream)
         InkPanel.Image = img

         ImageState = ImageStateEnum.Load

      Catch ex As Exception
         res = -1
         '* TODO: Ausnahmebehandlung
      End Try

      Return res
   End Function

   Private Sub ImageDraw(ByVal g As Graphics)

      Try

         If Plist.Count > 0 Then
            Dim bs As Byte() = New Byte(Plist.Count - 1) {}
            bs(0) = CByte(Drawing2D.PathPointType.Start)
            For a = 1 To Plist.Count - 1
               bs(a) = CByte(Drawing2D.PathPointType.Line)
               g.DrawPath(NewPen, New Drawing2D.GraphicsPath(Plist.ToArray, bs))
            Next
         End If

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub


#End Region

#Region "Controls: Events"

#Region "Events"

   Private Sub InkPanel_MouseDown(sender As Object, e As MouseEventArgs) Handles InkPanel.MouseDown

      Try

         If ImageState = ImageStateEnum.Empty Then
            ImageReset()
         End If

         DrawingMode = True
         Plist.Add(New Point(e.X, e.Y))
         NewPen = New Pen(PenColor, 3)

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

   Private Sub InkPanel_MouseUp(sender As Object, e As MouseEventArgs) Handles InkPanel.MouseUp

      Try

         If DrawingMode = True Then

            DrawingMode = False
            Using gr = Graphics.FromImage(bmp)
               ImageDraw(gr)
               gr.Flush()
            End Using
            Plist.Clear()
            InkPanel.Invalidate()

            ImageSave()

         End If

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

   Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles InkPanel.MouseMove
      Try

         If DrawingMode = True Then
            Plist.Add(New Point(e.X, e.Y))
            InkPanel.Invalidate()
         End If

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

   Private Sub InkPanel_MouseLeave(sender As Object, e As EventArgs) Handles InkPanel.MouseLeave

      Try

         'If DrawingMode = True Then
         '    DrawingMode = False
         'End If

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

   Private Sub InkPanel_Paint(sender As Object, e As PaintEventArgs) Handles InkPanel.Paint

      Try

         If DrawingMode = True Then
            ImageDraw(e.Graphics)
         End If

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub


   Private _
      Sub CommandButton_Click _
      ( _
         sender As Object, _
         e As EventArgs _
      ) _
      Handles _
              CommandReset.Click
      Dim res As Integer = 0

      Try

         Select Case CType(sender, Button).Name.ToLower()
            Case "CommandSave".ToLower()
               res = ImageSave()
            Case "CommandReset".ToLower()
               res = ImageReset()
               Me.Value = ""
         End Select

      Catch ex As Exception
         '* TODO: Ausnahmebehandlung
      End Try

   End Sub

#End Region

#End Region

End Class

<Serializable> _
Public Class InkSignChangedEventArgs
   Inherits System.EventArgs

   Private _UserClass As InkSignUserControl = Nothing

   Public ReadOnly Property Value As String
      Get
         If Object.Equals(_UserClass, Nothing) Then
            Return ""
         End If
         Return _UserClass.Value
      End Get
   End Property

   Public _
      Sub New _
      ( _
         ByVal UserClass As InkSignUserControl _
      )
      _UserClass = UserClass
   End Sub

End Class

<Serializable> _
Public Class InkSignItem

#Region "Members"

   '* Index
   Dim _Index As Integer = 0
   Public Property Index() As Integer
      Get
         Return _Index
      End Get
      Set(ByVal value As Integer)
         _Index = value
      End Set
   End Property

   '* Caption
   Dim _Caption As String = ""
   Public Property Caption() As String
      Get
         Return _Caption
      End Get
      Set(ByVal value As String)
         _Caption = value
      End Set
   End Property

#End Region

End Class
Seitenanfang