Übersetzen einer WinForms-Klasse zu WPF am Beispiel PictureBox

  • WPF

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    Übersetzen einer WinForms-Klasse zu WPF am Beispiel PictureBox

    Morgen allerseits,

    ich bin gerade dabei, eine WinForms-Klasse nach WPF zu übersetzen. Die Klasse erbt von einem Image. Vieles hab ich schon geschafft, wie z.B. den Timer umzustellen. Aber ich stosse hier an meine Grenzen:

    (1) Ich bräuchte das Pendant von PictureBox1.BackgroundImage und PictureBox1.Image für ein WPF-Image, da dieses diese Eigenschaften nicht bietet.

    (2) In Zeile 3 ist das Me rot unterstrichen:

    VB.NET-Quellcode

    1. Private WF As New Un4seen.Bass.Misc.WaveForm
    2. Private Sub SetupWaveForm()
    3. WF = New Misc.WaveForm(_Quelldatei, New Misc.WAVEFORMPROC(AddressOf MyWaveFormCallback), Me) 'Der Typ vom Wert "Wellenform" kann nicht in "Control" konvertiert werden:
    4. [...]
    5. End Sub


    (3) Und dann das hier:

    VB.NET-Quellcode

    1. Public Class Wellenform
    2. Inherits Image

    Da kommt:
    Die Image-Klasse hat kein zugreifbares Sub New() und kann nicht geerbt werden. Ich hab aber eine leere Sub New() reingeschrieben. Am Anfang hat er da nicht gemerckert, dann hab ich irgendwas in der Klasse geändert und seitdem ist es so. Ich weiss aber nicht mehr was das war.

    Ich freu mich auf eure Antworten :)
    Hallo

    Ich würde echt mal vorschlagen das du mal die ganze Klasse und mindestens ein Bild postest was das ganze werden soll und was es können soll. Verfasse bitte einen etwas detailierteren Post und wir sehen mal obs nicht einen besseren weg gibt.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m

    Na klar wie du meinst. Es soll eine Waveform einer MP3-Datei angezeigt werden (so wie im Screenshot im Anhang). Beachte dass du einen Verweis auf die bass.net.dll zufügen musst und die bass.dll ins Ausgabeverzeichnis kopieren musst. Beide Dateien gibts hier:
    un4seen.com/

    Hier die komplette Klasse:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports Un4seen.Bass
    3. Imports System.Windows.Threading
    4. Imports System.Drawing
    5. Public Class Wellenform
    6. Inherits Image
    7. Public Property Quelldatei As String
    8. Get
    9. Return _Quelldatei
    10. End Get
    11. Set(value As String)
    12. _Quelldatei = value
    13. End Set
    14. End Property
    15. Public Property Farbe As Color
    16. Get
    17. Return _Farbe
    18. End Get
    19. Set(value As Color)
    20. _Farbe = value
    21. End Set
    22. End Property
    23. Public Property Stream As Integer
    24. Get
    25. Return _Stream
    26. End Get
    27. Set(value As Integer)
    28. _Stream = value
    29. End Set
    30. End Property
    31. Private _Quelldatei As String
    32. Private _Farbe As Color
    33. Private _Stream As Integer
    34. #Region " Wave Form Drawing & Spektrum"
    35. ' Deklaration - Wave Form zeichnen
    36. Private IsDrawing As Boolean = False
    37. Private WF As New Un4seen.Bass.Misc.WaveForm
    38. Private _deviceLatencyBytes As Integer = 0
    39. #End Region
    40. #Region " updateTimer"
    41. Private _updateTimer As BASSTimer = Nothing
    42. Private _updateInterval As Integer = 50
    43. Private Channel_Pos As Long ' Position in bytes
    44. Private Channel_Len As Long ' Länge in bytes
    45. Public WithEvents Zeitgeber As DispatcherTimer = New DispatcherTimer
    46. #End Region
    47. Public Sub New()
    48. AddHandler Zeitgeber.Tick, AddressOf Zeitgeber_Tick
    49. Zeitgeber.Interval = New TimeSpan(0, 0, 0, 0, 100)
    50. End Sub
    51. Private Sub Zeitgeber_Tick(sender As Object, e As EventArgs) Handles Zeitgeber.Tick
    52. Channel_Pos = Bass.BASS_ChannelGetPosition(_Stream, BASSMode.BASS_POS_BYTES) ' Position in bytes
    53. Channel_Len = Bass.BASS_ChannelGetLength(_Stream, BASSMode.BASS_POS_BYTES) ' Länge in bytes
    54. If CType(Bass.BASS_ChannelIsActive(_Stream), BASSActive) = BASSActive.BASS_ACTIVE_PLAYING Then
    55. DrawWavePosition(Channel_Pos, Channel_Len) 'Wave Position updaten
    56. ElseIf CType(Bass.BASS_ChannelIsActive(_Stream), BASSActive) = BASSActive.BASS_ACTIVE_PAUSED Then
    57. DrawWavePosition(Channel_Pos, Channel_Len) 'Wave Position updaten
    58. Else
    59. _updateTimer.[Stop]()
    60. _updateTimer.[Dispose]()
    61. Exit Sub
    62. End If
    63. End Sub
    64. Private Sub SetupWaveForm()
    65. WF = New Misc.WaveForm(_Quelldatei, New Misc.WAVEFORMPROC(AddressOf MyWaveFormCallback), Me)
    66. WF.FrameResolution = 0.01F ' 10ms
    67. WF.CallbackFrequency = 500 ' alle 5 sekunden wird gerendert (500*10ms=5sec)
    68. 'Farben
    69. WF.ColorBackground = Color.Transparent
    70. WF.ColorLeft = _Farbe
    71. WF.ColorRight = _Farbe
    72. WF.ColorLeftEnvelope = _Farbe
    73. WF.ColorRightEnvelope = _Farbe
    74. WF.ColorMiddleLeft = _Farbe
    75. WF.ColorMiddleRight = _Farbe
    76. WF.DrawCenterLine = True
    77. WF.DrawEnvelope = True
    78. WF.DrawMarker = Misc.WaveForm.MARKERDRAWTYPE.Line Or Misc.WaveForm.MARKERDRAWTYPE.Name Or Misc.WaveForm.MARKERDRAWTYPE.NamePositionMiddle
    79. WF.RenderStart(True, BASSFlag.BASS_SAMPLE_FLOAT Or BASSFlag.BASS_STREAM_PRESCAN)
    80. WF.SyncPlayback(_Stream)
    81. End Sub
    82. Private Sub MyWaveFormCallback(ByVal framesDone As Integer, ByVal framesTotal As Integer, ByVal elapsedTime As TimeSpan, ByVal finished As Boolean)
    83. DrawWave(False)
    84. If finished Then
    85. DrawWave(True)
    86. End If
    87. End Sub
    88. Private Sub DrawWave(Optional ByVal highQuality As Boolean = False)
    89. If highQuality = False Then
    90. IsDrawing = Not IsDrawing
    91. If IsDrawing Then Exit Sub
    92. End If
    93. If Not WF Is Nothing Then
    94. Me.BackgroundImage = WF.CreateBitmap(Me.Width, Me.Height, -1, -1, highQuality)
    95. If WF.IsRenderingInProgress Then Exit Sub
    96. Else
    97. Me.BackgroundImage = Nothing
    98. End If
    99. End Sub
    100. Private Sub DrawWavePosition(ByVal pos As Long, ByVal len As Long)
    101. Dim PenColor As Color = _Farbe
    102. If len = 0 OrElse pos < 0 Then
    103. Me.Image = Nothing
    104. Return
    105. End If
    106. Dim bitmap As Bitmap = Nothing
    107. Dim g As Graphics = Nothing
    108. Dim p As Pen = Nothing
    109. Dim bpp As Double = 0
    110. Try
    111. bpp = len / CType(Me.Width, Double)
    112. pos -= _deviceLatencyBytes
    113. p = New Pen(PenColor)
    114. bitmap = New Bitmap(Me.Width, Me.Height)
    115. g = Graphics.FromImage(bitmap)
    116. g.Clear(Color.White)
    117. Dim x As Integer = CType(Math.Round(pos / bpp), Integer)
    118. ' position (x) = wo die Linie gezeichnet wird
    119. g.DrawLine(p, x, 0, x, Me.Height - 1)
    120. bitmap.MakeTransparent(Color.White)
    121. Catch
    122. bitmap = Nothing
    123. Finally
    124. ' Graphic Resourcen freigeben
    125. If Not p Is Nothing Then p.Dispose()
    126. If Not g Is Nothing Then g.Dispose()
    127. End Try
    128. Me.Image = bitmap
    129. End Sub
    130. Public Sub Start()
    131. _updateTimer = New Un4seen.Bass.BASSTimer(_updateInterval)
    132. AddHandler _updateTimer.Tick, AddressOf Zeitgeber_Tick
    133. SetupWaveForm()
    134. If _Stream <> 0 AndAlso Bass.BASS_ChannelPlay(_Stream, False) Then
    135. _updateTimer.[Start]()
    136. Else
    137. MessageBox.Show("Fehler!")
    138. End If
    139. MessageBox.Show(CStr(Bass.BASS_ErrorGetCode))
    140. End Sub
    141. End Class


    Vor dem Aufrufen der Public Sub Start(), die das Ganze anlaufen lassen soll, müssen die drei Eigenschaften noch gesetzt werden.

    Ich hoffe das sind genug Infos, ansonsten bitte nochmal melden.

    Edit: Hab ich noch vergessen: Damit das Ganze auch laufen kann musst du vorher in der Form_Loaded die bass.dll noch initialisieren und nen Track abspielen:

    VB.NET-Quellcode

    1. Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT Or BASSFlag.BASS_STREAM_PRESCAN, Me.Handle)
    2. strm = Bass.BASS_StreamCreateFile("C:\Test.mp3", 0, 0, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_STREAM_AUTOFREE Or BASSFlag.BASS_SAMPLE_FLOAT)

    Beim Festlegen der Propertys meiner Klasse nimmst du dann strm als Wellenform1.Stream und "C:\Test.mp3" als Wellenform1.Quelldatei und Wellenform1.Farbe die gewünschte Farbe der Waveform.

    Bilder
    • screenshot waveform.jpg

      41,62 kB, 909×96, 43 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    OK, ist schon eine recht spezielle sache. Ich spiel mich jetzt nicht mit irgendwelchen dll`s die Zeit habe ich leider nicht und ich will dir ja deine Arbeit auch nicht abnehmen. 8o
    Aber ein Problem wäre es nicht siehe hier: markheath.net/post/audio-waveform-drawing-using-wpf

    Da wird einfach ein Polygon innerhalb eines Canvas gezeichnet. schau jetzt nicht kompliziert aus. Es kommt dann nur darauf an wie und in welcher Form du die Daten aus der dll bekommst aber wie gesagt, ich kann mich jetzt nicht in die dll einlesen.

    Falls du dir die Arbeit nicht antun möchtest weist du ja mittlerweile wie man ein WinForms Control in WPF einbindet. Musst nur schaun wie hier das die Performance ist, ich habe da leider keine Erfahrungen machen können da ich es noch nie brauchte.

    Grüße
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##