bmp speichern mit e.Graphics.DrawLine in PictureBox_Paint

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.


    For Each items As Object In Panel_AK_X.Controls

    ->

    VB.NET-Quellcode

    1. For Each items As Control In Panel_AK_X.Controls

    Vorallem da alles was du anschließend damit machst unabhängig vom Typ des Controls ist kannst du dir auch die beiden TypeOf überprüfungen sparen(die kosten relativ viel Zeit).

    Ich weiß nicht wie gut VB.Net inzwischen ist aber evtl. geht auch das

    VB.NET-Quellcode

    1. For Each items In Panel_AK_X.Controls

    das würde(also sowas geht halt in C#) dann den Typ für die items automatisch aus der Controls Collection deduzieren, ist aber somit von der Bedeutung her exakt dasselbe wie mein obiger Code.

    Abgesehen davon sieht mir das nicht nach einem Sinnvollen aufbau aus.
    Was genau macht denn dieser Code zum Beispiel? Ich sehe wenig Sinn davon Controls zu entfernen und dann auch noch so selektiv. Warum dann nicht alle in einem Panel sammeln und einfach das Panel löschen?
    Warum haben die Controls alle Namen entsprechend der selektierten DGV Zeile? Erstellst du etwa für jeden Eintrag in der DGV zugehörige Controls? Wie sieht der Aufbau der Controls aus(Screenshot)?
    Denn dynamisch Controls erzeugen ist oftmals nicht sehr sinnvoll. Vorallem da Controls in WinForms(ob dus glaubst oder nicht) ist jedes Control welches Events empfangen kann ein extra "Window" deshalb werden viele Controls auf einmal auch gerne langsam, weil für jedes Control viele Dinge gemacht werden, die du vmtl. gar nicht brauchst für diesen Fall. Ich denke hier muss evtl. ein UserControl her

    Edit: Noch zu der Frage spätes binden selektiv zu zu lassen:
    In C# gibt es dafür das dynamic-Keyword in Vb.Net gibt es ein solches Äquivalent meines Wissens noch nicht. In VB.Net kann man für ein einzelnes Dokument mittels Option Strict Off spätes binden zu lassen.
    Aber ich sage es noch einmal das wirst du in sehr wenigen Fällen benötigen. Ich selbst habe es noch nie benötigt, da ich als Programmierer immer weiß was ich aufrufen will und auf welches Objekt und die dann entweder eine gemeinsame Basisklasse haben oder auch ein Objekt sind dessen struktur ich kenn, kann man mit Reflection die MethodInfo holen und mittels Expression API einen Aufruf erzeugen, der die nötige Konvertierung in den richtigen Typen vornimmt, da dann für jeden Aufruf für jedes Objekt nur der Code einmal generiert werden muss, ist das natürlich wesentlich performanter als dies bei jedem Aufruf aufs neue zu machen, was durch das späte Binden auf ähnliche weiße passiert.
    Diesen letzten Abschnitt musst du auch nicht unbedingt verstehen, weil auch diese Dinge braucht man dann doch erst für ziemlich fortgeschrittene Sachen. Ich denke nicht, dass wir für dieses Projekt darauf zurückgreifen müssen.
    Und wie du sehen kannst können wir die Fehler doch ziemlich leicht beheben. Wenn man halt mal ein Projekt mit Option Strict Off gemacht hat und sich nicht aus kennt hat man halt viel Arbeit, aber da du in Zukunft jedes Projekt mit Option Strict On machen wirst, wirst du diese Probleme in der Zukunft auch immer nur für den Moment und die einzelne Code Zeile haben und mit der Zeit Wissen was zu tun ist, bist du diese Fehler nicht mal mehr beim schreiben von Code auf dem Papier machst.
    Denn solche Fehler werden ansonsten nur in Typ unsicheren Sprachen zugelassen die idR auch eher auf Duck-Typing bauen.
    Java, C#, Vb.Net, C++ uvm. sind typsichere Sprachen(und gefallen mir in aller Regel auch besser, da man bei Typ-unsicheren Sprachen Code erst ausführen muss um Typ-Fehler zu finden, hier weiß man es zur Compiletime)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jvbsl“ ()

    Also dann mal etwas Code und ein Bildchen. Der "sender"-Quatsch und die korrekte Definition der Variablen machen ich noch. Bitte einfach drüber hinweg schauen.

    Erzeugen der PictureBox und Labels:

    VB.NET-Quellcode

    1. Private Sub DGV_N_X_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGV_N_X.CellEndEdit
    2. Dim picBoxF As New PictureBox
    3. Dim picBoxFa As New PictureBox
    4. Dim LabelnameF As New Label
    5. If sender.Rows(e.RowIndex).Cells("bezeichnungX").Value = "" Then
    6. Try
    7. sender.Rows(e.RowIndex).Cells("bezeichnungX").Value = "F" & e.RowIndex
    8. Catch ex As Exception
    9. End Try
    10. ' den Panel das Objekt hinzufügen
    11. Panel_AK_X.Controls.Add(picBoxF)
    12. Panel_AK_X.Controls.Add(LabelnameF)
    13. ' Def der PictureBox der Kraft
    14. With picBoxF
    15. .ImageLocation = Modul_Speicherort.ort_Bilder & "SPfeilr.jpg"
    16. .Size = New Point(pfx.Size.Width, pfx.Size.Height)
    17. .Location = New Point(0, pfx.Location.Y)
    18. .SizeMode = PictureBoxSizeMode.Zoom
    19. .Name = "pf_" & DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value & "x"
    20. ToolTip1.SetToolTip(picBoxF, strTeilen(.Name, "_", True) & "= " & _
    21. DGV_N_X.Rows(e.RowIndex).Cells("nameValueX").Value & _
    22. ToolStripCB_kraftEinheit.Text & ", " & _
    23. "L= " & DGV_N_X.Rows(e.RowIndex).Cells("laengeX").Value & _
    24. ToolStripCB_laengeEinheit.Text)
    25. End With
    26. ' Def des Labels
    27. With LabelnameF
    28. .Location = New Point(0, nameFx.Location.Y)
    29. .Width = 25
    30. .Text = DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value
    31. .Name = "name_" & DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value & "x"
    32. End With
    33. End If
    34. ' Def der PictureBox der Axialkraft
    35. If sender.Rows(e.RowIndex).Cells("nameAxialValueX").Value <> "" And sender.Rows(e.RowIndex).Cells("nameAxialValueX").Value <> "0" And _
    36. Not (TypeOf Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value & "axialX") Is PictureBox) Then
    37. Panel_AK_X.Controls.Add(picBoxFa)
    38. With picBoxFa
    39. .ImageLocation = Modul_Speicherort.ort_Bilder & "SPfeilS.jpg"
    40. .Size = New Point(pfFax.Size.Width, pfFax.Size.Height)
    41. .Location = New Point(Panel_AK_X.Controls( _
    42. "pf_" & DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value & "x").location.X, pfFax.Location.Y)
    43. .SizeMode = PictureBoxSizeMode.Zoom
    44. .Name = "pf_" & DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value & "axialX"
    45. .BringToFront()
    46. End With
    47. End If
    48. For Each items In DGV_N_X.Rows(e.RowIndex).Cells
    49. If items.Value = "FB" Then Exit For
    50. If items.ColumnIndex <> e.ColumnIndex And items.Value = "" Then
    51. items.Value = "0"
    52. End If
    53. If DGV_N_X.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "" Then DGV_N_X.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "0"
    54. Next items
    55. If DGV_N_X.Rows(0).Cells("bezeichnungX").Value() = "FB" Then DGV_N_Y.Rows(0).Cells("laengeY").Value = DGV_N_X.Rows(0).Cells("laengeX").Value : Call updatePfy()
    56. Try
    57. ReDim toFAx(DGV_N_X.RowCount - 2, 1)
    58. toFAx(e.RowIndex, 0) = DGV_N_X.Rows(e.RowIndex).Cells("bezeichnungX").Value
    59. toFAx(e.RowIndex, 1) = DGV_N_X.Rows(e.RowIndex).Cells("laengeX").Value
    60. Catch ex As Exception
    61. End Try
    62. Call updatePFx()
    63. End Sub


    Wenn dann User-Eingaben in der DVG geändert werden, wird die Position der Pfeile auch geändert.

    VB.NET-Quellcode

    1. Sub updatePFx()
    2. ReDim toFAx(DGV_N_X.RowCount - 2, 1)
    3. For index As Integer = 0 To DGV_N_X.Rows.Count - 2
    4. toFAx(index, 0) = DGV_N_X.Rows(index).Cells("bezeichnungX").Value
    5. toFAx(index, 1) = DGV_N_X.Rows(index).Cells("laengeX").Value
    6. Next
    7. minX = 0 : maxX = 0
    8. For index As Integer = 0 To toFAx.GetUpperBound(0)
    9. If minX > toFAx(index, 1) Then minX = toFAx(index, 1)
    10. If maxX < toFAx(index, 1) Then maxX = toFAx(index, 1)
    11. Next
    12. ratioX = NMx / (maxX + Math.Abs(minX))
    13. pf_FAx.Location = New Point(Math.Abs(minX) * ratioX, pf_FAx.Location.Y)
    14. name_FAx.Location = New Point(pf_FAx.Location.X, name_FAx.Location.Y)
    15. For Each items As Object In Panel_AK_X.Controls
    16. If (TypeOf items Is PictureBox) Then
    17. If strTeilen(items.Name, "_", False) = "pf_" Then
    18. Dim index0 As Integer = 0
    19. For Each rows As DataGridViewRow In DGV_N_X.Rows
    20. If "pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "x" = items.Name Then
    21. Select Case True
    22. Case DGV_N_X.Rows(index0).Cells("laengeX").Value = Nothing
    23. items.Location = New Point(0, items.Location.Y)
    24. With Panel_AK_X.Controls("name_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "x")
    25. .Location = New Point(items.location.X, .location.Y)
    26. End With
    27. If items.name <> "pf_FBx" And (TypeOf Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX") Is PictureBox) Then
    28. With Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX")
    29. .Location = New Point(items.location.X, .location.Y)
    30. End With
    31. End If
    32. Case DGV_N_X.Rows(index0).Cells("laengeX").Value < 0
    33. items.Location = New Point(pf_FAx.Location.X + ((DGV_N_X.Rows(index0).Cells("laengeX").Value) * ratioX), items.Location.Y)
    34. With Panel_AK_X.Controls("name_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "x")
    35. .Location = New Point(items.location.X, .location.Y)
    36. End With
    37. If items.name <> "pf_FBx" And (TypeOf Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX") Is PictureBox) Then
    38. With Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX")
    39. .Location = New Point(items.location.X, .location.Y)
    40. End With
    41. End If
    42. Case Else
    43. items.Location = New Point(pf_FAx.Location.X + (DGV_N_X.Rows(index0).Cells("laengeX").Value * ratioX), items.Location.Y)
    44. With Panel_AK_X.Controls("name_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "x")
    45. .Location = New Point(items.location.X, .location.Y)
    46. End With
    47. If items.name <> "pf_FBx" And (TypeOf Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX") Is PictureBox) Then
    48. With Panel_AK_X.Controls("pf_" & DGV_N_X.Rows(index0).Cells("bezeichnungX").Value & "axialX")
    49. .Location = New Point(items.location.X, .location.Y)
    50. End With
    51. End If
    52. End Select
    53. ToolTip1.SetToolTip(items, strTeilen(items.Name, "_", True) & "= " & _
    54. DGV_N_X.Rows(index0).Cells("nameValueX").Value & _
    55. ToolStripCB_kraftEinheit.Text & ", " & _
    56. "L= " & DGV_N_X.Rows(index0).Cells("laengeX").Value & _
    57. ToolStripCB_laengeEinheit.Text)
    58. End If
    59. index0 = index0 + 1 * 1
    60. Next
    61. End If
    62. End If
    63. Next
    64. End Sub


    Der User kann auch Kräfte "Zeilen der DGV, die Pfeile und Labels" entfernen:

    VB.NET-Quellcode

    1. Private Sub B_delateRowY_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B_delateRowNY.Click
    2. Dim index0 As Integer = 0
    3. Dim delateRow As String
    4. Dim PB, LA As Boolean
    5. PB = False : LA = False
    6. Try
    7. If Not (DGV_N_Y.CurrentRow.Index = 0) Then
    8. delateRow = DGV_N_Y.Rows(DGV_N_Y.CurrentRow.Index).Cells("bezeichnungY").Value
    9. For Each items As Object In Panel_AK_Y.Controls
    10. If (TypeOf items Is PictureBox) Then
    11. If items.Name = "pf_" & DGV_N_Y.Rows(DGV_N_Y.CurrentRow.Index).Cells("bezeichnungY").Value & "y" Then _
    12. Panel_AK_Y.Controls.RemoveByKey(items.Name) : Panel_AK_Y.Update()
    13. If items.Name = "pf_" & DGV_N_Y.Rows(DGV_N_Y.CurrentRow.Index).Cells("bezeichnungY").Value & "axialY" Then _
    14. Panel_AK_Y.Controls.RemoveByKey(items.Name) : Panel_AK_Y.Update()
    15. End If
    16. If (TypeOf items Is Label) Then
    17. If items.Name = "name_" & DGV_N_Y.Rows(DGV_N_Y.CurrentRow.Index).Cells("bezeichnungY").Value & "y" Then _
    18. Panel_AK_Y.Controls.RemoveByKey(items.Name) : Panel_AK_Y.Update()
    19. End If
    20. Next
    21. DGV_N_Y.Rows.RemoveAt(DGV_N_Y.CurrentRow.Index)
    22. For Each rows As DataGridViewRow In DGV_N_Y.Rows
    23. If DGV_N_Y.Rows(index0).Cells("bezeichnungY").Value <> "FB" Then
    24. For Each items As Object In Panel_AK_Y.Controls
    25. If (TypeOf items Is PictureBox) Then
    26. If items.name = "pf_" & DGV_N_Y.Rows(index0).Cells("bezeichnungY").Value & "y" Then
    27. items.name = "pf_F" & index0 & "y"
    28. PB = True
    29. End If
    30. If items.name = "pf_" & DGV_N_Y.Rows(index0).Cells("bezeichnungY").Value & "axialY" Then
    31. items.name = "pf_F" & index0 & "axialY"
    32. PB = True
    33. End If
    34. End If
    35. If (TypeOf items Is Label) Then
    36. If items.name = "name_" & DGV_N_Y.Rows(index0).Cells("bezeichnungY").Value & "y" Then
    37. items.name = "name_F" & index0 & "y"
    38. items.text = "F" & index0
    39. LA = True
    40. End If
    41. End If
    42. Next
    43. If PB = True And LA = True Then
    44. DGV_N_Y.Rows(index0).Cells("bezeichnungY").Value = "F" & index0
    45. PB = False : LA = False
    46. End If
    47. End If
    48. index0 = index0 + 1 * 1
    49. Next
    50. Call updatePfy()
    51. End If
    52. Catch ex As Exception
    53. End Try
    54. End Sub


    Das schreit nach einem neuen Datentyp, welcher jeweils eine gesonderte Kraft beschreibt.

    Dann kannst du ein UserControl machen, das anstelle mit PictureBoxen und Labels über GDI+ alles zeichnet.
    Die enthalten eine ObservableCollection(Of der Kräfte, welche du somit über eine schleife zeichnest. Das DataGridView kannst du dann über Databinding an diese Kräfte binden und sobald sich in der Liste was ändert, ändert sich das im DGV automatisch. Umgekehrt musst du bei WinForms meines Wissens leider noch manuell machen. Aber allemal einfacher und übersichtlicher als die ganzen Controls zu erzeugen
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Icke schrieb:

    Damit ich das richtig verstehe:
    Das hast Du genau richtig verstanden. :thumbup:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!