Temat: Zapis/odczyt do/z pliku XML
Dodamy do aplikacji nowe funkcjonalności:Zapis i odczyt do/z pliku XML, pojedynczego stopnia wału serializacją i zapis całego wału do pliku XML, tekstowo.
Odczyt całego wałka z pliku XML, tekstowo, pominięto – ze względu na to, ze nie wnosi nowych pojęć, a zawiera wiele linii kodu.
Uzupełnimy też aplikację o możliwość zmiany średnicy i długości wskazanego stopnia wału.
Dodamy pozycje menu:
XML
- Zapisz stopień - Czytaj stopień - Zapisz wałek
Wymiary
- Średnica stopnia - Długość stopnia
Dodamy do zmiennej wyliczeniowej wartości:
XMLZapiszStopien SrednicaStopnia DlugoscStopnia
Metoda XMLZapisz
Do wszystkich klas definiujących stopnie, czyli do klasy bazowej Stopien_walu oraz do klas pochodnych StopienFazaZLewej, StopienFazaZPrawej dodamy metodę XMLZapisz – zapisującą parametry, wskazanego myszą stopnia, do pliku XML serializacją, W klasie bazowej będzie to metoda z atrybutem Overridable, a w klasach pochodnych z atrybutem Overrides:.
Zapis parametrów całego wałka do pliku XML wykonamy zwykłą procedurą, bez serializacji.
Odczyt parametrów całego wałka z pliku XML pominiemy, ze względu na żmudność i pracochłonność kodu.
Zapis całego wałka do pliku xml
Aby określić, przy zapisie całego wałka do pliku XML, czy stopień ma i jaką modyfikację - dodamy do klasy bazowej Stopien_walu właściwość typu tekstowego o nazwie powStopnia zawierającą tekst
"Bez_modyfikacji" lub "Pret" lub "Gwint". Określenie jaki ostatecznie tekst będzie zawarty w tej właściwości zostanie wykonane odpowiednim konstruktorem New tej właściwości.
Menu Wymiary
Pozycja menu Wymiary pozwala zmieniać wymiary średnicy lub długości stopnia poprzez zmianę tych właściwości dla wskazanego myszą (klikniętego) stopnia.
Aby obsłużyć komunikację z plikami dodamy do aplikacji przestrzeń nazw System.IO, a aby skorzystać z obiektów XML i serializacji – przestrzeń nazw System.Xml.
Class1.vb
Imports System.IO Imports System.Xml
Public Class Stopien_walu
Protected _Srednica_stopnia As Single Protected _Dlugosc_stopnia As Single
Protected _powStopnia As Modyfikacja_stopnia Sub New()
_powStopnia = New Bez_modyfikacji End Sub
Public Property Srednica_stopnia As Single Get
Return _Srednica_stopnia End Get
Set(value As Single)
_Srednica_stopnia = value End Set
End Property
Public Property Dlugosc_stopnia As Single Get
Return _Dlugosc_stopnia End Get
Set(value As Single)
_Dlugosc_stopnia = value End Set
End Property
Public Property powStopnia As String Get
Return _powStopnia.GetType.Name.ToString End Get
Set(value As String)
If value = "Bez_modyfikacji" Then _powStopnia = New Bez_modyfikacji ElseIf value = "Pret" Then
_powStopnia = New Pret ElseIf value = "Gwint" Then _powStopnia = New Gwint(8) End If
End Set End Property
Public Overridable Sub Rysuj(ByVal objRys As Graphics, ByVal objPioro As Pen, ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia zykłego, czyli prostokąta
objRys.DrawRectangle(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2, _ _Dlugosc_stopnia, _Srednica_stopnia)
_powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Overridable Sub XMLZapisz()
Dim SerializacjaDoPlikuXml As Serialization.XmlSerializer
Dim plikXML As FileStream = New FileStream("Dane_stopnia.xml", FileMode.Create, _ FileAccess.Write, FileShare.None) SerializacjaDoPlikuXml = New Serialization.XmlSerializer(GetType(Stopien_walu)) SerializacjaDoPlikuXml.Serialize(plikXML, Me)
plikXML.Close() End Sub
Public Sub ZmienPowierzchnieNaZwykla() _powStopnia = New Bez_modyfikacji End Sub
Public Overridable Sub ZmienPowierzchnieNaPret() _powStopnia = New Pret
End Sub
Public Overridable Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(8)
End Sub End Class
Public Class StopienFazaZLewej Inherits Stopien_walu
Private _faza As Single
Public Property Faza As Single Get
Return _faza End Get
Set(value As Single) _faza = value End Set
End Property
Public Overrides Sub Rysuj(ByVal objRys As System.Drawing.Graphics, _ ByVal objPioro As Pen,
ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia z fazą z lewej strony
objRys.DrawRectangle(objPioro, pozycja_x + _faza, pozycja_y - _Srednica_stopnia / 2, _
_Dlugosc_stopnia - _faza, _Srednica_stopnia) objRys.DrawLine(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2 + _faza, _ pozycja_x + _faza, pozycja_y - _Srednica_stopnia / 2) objRys.DrawLine(objPioro, pozycja_x, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _faza, pozycja_y + _Srednica_stopnia / 2) objRys.DrawLine(objPioro, pozycja_x, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x, pozycja_y - _Srednica_stopnia / 2 + _faza) _powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Overrides Sub XMLZapisz()
Dim SerializacjaDoPlikuXml As Serialization.XmlSerializer
Dim plikXML As FileStream = New FileStream("Dane_stopnia.xml", FileMode.Create, _ FileAccess.Write, FileShare.None) SerializacjaDoPlikuXml = _
New Serialization.XmlSerializer(GetType(StopienFazaZLewej)) SerializacjaDoPlikuXml.Serialize(plikXML, Me)
plikXML.Close() End Sub
Public Overrides Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(_faza)
End Sub
Public Overrides Sub ZmienPowierzchnieNaPret()
MsgBox("Na tym stopniu nie można zbudować pręta") End Sub
End Class
Public Class StopienFazaZPrawej Inherits Stopien_walu
Private _faza As Single
Public Property Faza As Single Get
Return _faza End Get
Set(value As Single) _faza = value End Set
End Property
Public Overrides Sub Rysuj(ByVal objRys As System.Drawing.Graphics, _ ByVal objPioro As Pen,
ByVal pozycja_x As Single, ByVal pozycja_y As Single) 'Rysowanie stopnia z fazą z prawej strony
objRys.DrawRectangle(objPioro, pozycja_x, pozycja_y - _Srednica_stopnia / 2, _ _Dlugosc_stopnia - _faza, _Srednica_stopnia) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y - _Srednica_stopnia / 2 + _faza, _ pozycja_x + _Dlugosc_stopnia - _faza, pozycja_y - _Srednica_stopnia / 2) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _Dlugosc_stopnia - _faza, pozycja_y + _Srednica_stopnia / 2) objRys.DrawLine(objPioro, _
pozycja_x + _Dlugosc_stopnia, pozycja_y + _Srednica_stopnia / 2 - _faza, _ pozycja_x + _Dlugosc_stopnia, pozycja_y - _Srednica_stopnia / 2 + _faza) _powStopnia.Narysuj(objRys, pozycja_x, pozycja_y, Me) 'Rysowanie modyfikacji End Sub
Public Overrides Sub XMLZapisz()
Dim SerializacjaDoPlikuXml As Serialization.XmlSerializer
Dim plikXML As FileStream = New FileStream("Dane_stopnia.xml", FileMode.Create, _ FileAccess.Write, FileShare.None) SerializacjaDoPlikuXml = _
New Serialization.XmlSerializer(GetType(StopienFazaZPrawej)) SerializacjaDoPlikuXml.Serialize(plikXML, Me)
plikXML.Close() End Sub
Public Overrides Sub ZmienPowierzchnieNaGwint() _powStopnia = New Gwint(_faza)
End Sub
Public Overrides Sub ZmienPowierzchnieNaPret()
MsgBox("Na tym stopniu nie można zbudować pręta") End Sub
End Class
'Nowa klasa – Modyfikacja_stopnia + 3 klasy potomne(1) Bez_modyfikacji, (2) Pret, (3) Gwint
Public MustInherit Class Modyfikacja_stopnia
Public MustOverride Sub Narysuj(ByVal objRys As Graphics, _
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu) End Class
Public Class Bez_modyfikacji Inherits Modyfikacja_stopnia
Public Overrides Sub Narysuj(ByVal objRys As Graphics, ByVal pozycja_x As Single, _ ByVal pozycja_y As Single, ByVal st As Stopien_walu) End Sub
End Class
Public Class Pret
Inherits Modyfikacja_stopnia
Public Overrides Sub Narysuj(ByVal objRys As Graphics,
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu)
'Rysowanie modyfikacji czyli Pręta na stopniu Dim objPioro As New Pen(Color.Red, 1)
'Linia 1-3
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y + st.Srednica_stopnia / 2, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y - st.Srednica_stopnia / 2) 'Linia 2-4
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y - st.Srednica_stopnia / 2, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y + st.Srednica_stopnia / 2) End Sub
End Class
Public Class Gwint
Inherits Modyfikacja_stopnia Private _gwint As Single
Sub New(ByVal glebokosc_gwintu As Single) _gwint = glebokosc_gwintu
End Sub
Public Overrides Sub Narysuj(ByVal objRys As Graphics,
ByVal pozycja_x As Single, ByVal pozycja_y As Single, ByVal st As Stopien_walu)
'Rysowanie modyfikacji czyli Gwintu na stopniu
Dim objPioro As New System.Drawing.Pen(Brushes.Red, 1) 'Linia 1-2
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y - st.Srednica_stopnia / 2 + _gwint, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y - st.Srednica_stopnia / 2 + _gwint) 'Linia 4-3
objRys.DrawLine(objPioro, _
pozycja_x, pozycja_y + st.Srednica_stopnia / 2 - _gwint, _
pozycja_x + st.Dlugosc_stopnia, pozycja_y + st.Srednica_stopnia / 2 - _gwint) End Sub
End Class
Public Enum TrybPracy NicNieRob
NowyStopien UsunStopien StworzGwint StworzPret UsunModyfikacje XMLZapiszStopien SrednicaStopnia DlugoscStopnia End Enum
Form1.vb
Imports System.IO Imports System.Xml
Public Class Form1
Dim objRys As System.Drawing.Graphics
Dim objPioroWal As New System.Drawing.Pen(Color.Red, 2) Dim objPioroOs As New System.Drawing.Pen(Color.Green) Dim X_osi As Integer = 50
Dim Y_osi As Integer = 200 Dim x_pocz As Integer = X_osi Dim mode As TrybPracy
Dim Kolekcja_stopni_walu As New List(Of Stopien_walu) Dim faza As Single
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) _
Handles MyBase.MouseMove LabelKoordynaty.Text = "X=" & e.X & " Y=" & e.Y
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load objRys = Me.CreateGraphics
mode = TrybPracy.NicNieRob End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint Call RysujOsie()
End Sub
Private Sub RysujOsie()
objRys.DrawLine(objPioroOs, X_osi, 50, X_osi, 350) objRys.DrawLine(objPioroOs, X_osi, Y_osi, 700, Y_osi) End Sub
Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) _
Handles MyBase.MouseClick Dim x1 As Single
Dim y1 As Single
Dim mojStopien As Stopien_walu
''Dim mojStopien As New Stopien_walu Dim mojStopienL As StopienFazaZLewej Dim mojStopienP As StopienFazaZPrawej Dim wymiar_temp As String
x1 = e.X y1 = e.Y
If mode = TrybPracy.NowyStopien Then ''mojStopien = New Stopien_walu If faza = 0 Then
mojStopien = New Stopien_walu Else
If faza > 0 Then
mojStopienL = New StopienFazaZLewej mojStopienL.Faza = faza
mojStopien = mojStopienL Else
mojStopienP = New StopienFazaZPrawej mojStopienP.Faza = Math.Abs(faza) mojStopien = mojStopienP
End If End If
mojStopien.Dlugosc_stopnia = x1 - x_pocz
mojStopien.Srednica_stopnia = (Y_osi - y1) * 2
mojStopien.Rysuj(objRys, objPioroWal, x_pocz, Y_osi) x_pocz = x_pocz + mojStopien.Dlugosc_stopnia
Kolekcja_stopni_walu.Add(mojStopien) ElseIf mode = TrybPracy.UsunStopien Then
Kolekcja_stopni_walu.Remove(KliknietyStopien(x1)) Call Odswiez()
ElseIf mode = TrybPracy.UsunModyfikacje Then mojStopien = KliknietyStopien(x1)
mojStopien.ZmienPowierzchnieNaZwykla() Call Odswiez()
ElseIf mode = TrybPracy.StworzPret Then mojStopien = KliknietyStopien(x1) mojStopien.ZmienPowierzchnieNaPret() Call Odswiez()
ElseIf mode = TrybPracy.StworzGwint Then mojStopien = KliknietyStopien(x1) mojStopien.ZmienPowierzchnieNaGwint() Call Odswiez()
ElseIf mode = TrybPracy.XMLZapiszStopien Then mojStopien = KliknietyStopien(x1, y1) mojStopien.XMLZapisz()
MsgBox("Plik XML został zapisany.") ElseIf mode = TrybPracy.SrednicaStopnia Then mojStopien = KliknietyStopien(x1, y1)
wymiar_temp = InputBox("Podaj nową Średnicę stopnia", _ "Zmiana Średnicy stopnia", _ mojStopien.Srednica_stopnia) If wymiar_temp <> "" Then
mojStopien.Srednica_stopnia = wymiar_temp End If
Call Odswiez()
ElseIf mode = TrybPracy.DlugoscStopnia Then mojStopien = KliknietyStopien(x1, y1)
wymiar_temp = InputBox("Podaj nową Długość stopnia", _ "Zmiana Długości stopnia", _
CStr(mojStopien.Dlugosc_stopnia)) If wymiar_temp <> "" Then
mojStopien.Dlugosc_stopnia = wymiar_temp End If
Call Odswiez() End If
End Sub
Private Sub NowyWałekToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles NowyWałekToolStripMenuItem.Click mode = TrybPracy.NicNieRob
x_pocz = X_osi
Kolekcja_stopni_walu.Clear()
objRys.Clear(SystemColors.Control) Call RysujOsie()
End Sub
Private Sub StopnieBezFazyToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles StopnieBezFazyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = 0 End Sub
Private Sub NicNieRóbToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles NicNieRóbToolStripMenuItem.Click mode = TrybPracy.NicNieRob
End Sub
Private Sub SkasujToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles SkasujToolStripMenuItem.Click objRys.Clear(SystemColors.Control)
Call RysujOsie() End Sub
Private Sub PokażToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles PokażToolStripMenuItem.Click Call Narysuj()
End Sub
Private Sub Narysuj()
Dim wsk_kolekcji As Stopien_walu x_pocz = X_osi
For Each wsk_kolekcji In Kolekcja_stopni_walu wsk_kolekcji.Rysuj(objRys, x_pocz, Y_osi) x_pocz = x_pocz + wsk_kolekcji.Dlugosc_stopnia Next
End Sub
Private Sub StopnieZFaząZLewejStronyToolStripMenuItem_Click(sender As Object, _ e As EventArgs) Handles StopnieZFaząZLewejStronyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = 8 End Sub
Private Sub StopnieZFaząZPrawejStronyToolStripMenuItem_Click(sender As Object, _ e As EventArgs) Handles StopnieZFaząZPrawejStronyToolStripMenuItem.Click mode = TrybPracy.NowyStopien
faza = -8 End Sub
Private Sub UsuńStopieńToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles UsuńStopieńToolStripMenuItem.Click mode = TrybPracy.UsunStopien
End Sub
Private Sub Odswiez()
objRys.Clear(SystemColors.Control) Call Narysuj()
Call RysujOsie() 'Ewentualnie, jeśli system "się leni" :-) End Sub
Private Function KliknietyStopien(ByVal x As Single) As Stopien_walu Dim x_temp As Single = X_osi
Dim i As Integer = 0
Do Until x > x_temp And x <= _
x_temp + Kolekcja_stopni_walu.Item(i).Dlugosc_stopnia x_temp = x_temp + Kolekcja_stopni_walu.Item(i).Dlugosc_stopnia
i = i + 1 Loop
Return Kolekcja_stopni_walu.Item(i) End Function
Private Sub GwintToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles GwintToolStripMenuItem.Click mode = TrybPracy.StworzGwint
End Sub
Private Sub PrętToolStripMenuItem_Click(sender As Object, e As EventArgs) _
Handles PrętToolStripMenuItem.Click mode = TrybPracy.StworzPret
End Sub
Private Sub UsuńModyfikacjęToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles UsuńModyfikacjęToolStripMenuItem.Click mode = TrybPracy.UsunModyfikacje
End Sub
Private Sub ZapiszStopieńToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles ZapiszStopieńToolStripMenuItem.Click mode = TrybPracy.XMLZapiszStopien
End Sub
Private Sub CzytajStopieńToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles CzytajStopieńToolStripMenuItem.Click Dim Linia, Klasa As String
FileOpen(1, "Dane_stopnia.xml", OpenMode.Input) Linia = LineInput(1)
Linia = LineInput(1)
Klasa = Mid(Linia, 2, InStr(Linia, " ") - 2) FileClose(1)
Dim mojStopien As New Stopien_walu
Dim PlikDanych As FileStream = File.Open("Dane_stopnia.xml", FileMode.Open, _ FileAccess.Read) Dim MojaSerializacja As Serialization.XmlSerializer
If Klasa = "StopienFazaZLewej" Then MojaSerializacja = _
New Serialization.XmlSerializer(GetType(StopienFazaZLewej)) ElseIf Klasa = "StopienFazaZPrawej" Then
MojaSerializacja = _
New Serialization.XmlSerializer(GetType(StopienFazaZPrawej)) Else
MojaSerializacja = New Serialization.XmlSerializer(GetType(Stopien_walu)) End If
mojStopien = MojaSerializacja.Deserialize(PlikDanych) PlikDanych.Close()
Kolekcja_stopni_walu.Add(mojStopien) Call Odswiez()
End Sub
Private Sub ZapiszWałekToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles ZapiszWałekToolStripMenuItem.Click Dim plik As String
plik = "Dane_walka.xml"
FileOpen(1, plik, OpenMode.Output)
PrintLine(1, "<?xml version=" & Chr(34) & "1.0" & Chr(34) & "?>") PrintLine(1, "<Walek xmlns:xsi=" & Chr(34) & _
"http://www.w3.org/2001/XMLSchema-instance" & Chr(34) & _
" xmlns:xsd=" & Chr(34) & "http://www.w3.org/2001/XMLSchema" & _ Chr(34) & ">")
For Each wsk_kolekcji In Kolekcja_stopni_walu
If wsk_kolekcji.GetType.Name.ToString = "Stopien_walu" Then PrintLine(1, "<Stopien_walu>")
PrintLine(1, " <Srednica_stopnia>" & _
wsk_kolekcji.Srednica_stopnia.ToString & "</Srednica_stopnia>") PrintLine(1, " <Dlugosc_stopnia>" & _
wsk_kolekcji.Dlugosc_stopnia.ToString & "</Dlugosc_stopnia>") PrintLine(1, " <powStopnia>" & wsk_kolekcji.powStopnia.ToString & _
"</powStopnia>") PrintLine(1, "</Stopien_walu>")
ElseIf wsk_kolekcji.GetType.Name.ToString = "StopienFazaZLewej" Then PrintLine(1, "<StopienFazaZLewej>")
PrintLine(1, " <Srednica_stopnia>" & _
wsk_kolekcji.Srednica_stopnia.ToString & "</Srednica_stopnia>") PrintLine(1, " <Dlugosc_stopnia>" & _
wsk_kolekcji.Dlugosc_stopnia.ToString & "</Dlugosc_stopnia>") PrintLine(1, " <powStopnia>" & wsk_kolekcji.powStopnia.ToString & _ "</powStopnia>")
Dim st As New StopienFazaZLewej st = wsk_kolekcji
PrintLine(1, " <Faza>" & st.Faza.ToString & "</Faza>") PrintLine(1, "</StopienFazaZLewej>")
ElseIf wsk_kolekcji.GetType.Name.ToString = "StopienFazaZPrawej" Then PrintLine(1, "<StopienFazaZPrawej>")
PrintLine(1, " <Srednica_stopnia>" & _
wsk_kolekcji.Srednica_stopnia.ToString & "</Srednica_stopnia>") PrintLine(1, " <Dlugosc_stopnia>" & _
wsk_kolekcji.Dlugosc_stopnia.ToString & "</Dlugosc_stopnia>") PrintLine(1, " <powStopnia>" & wsk_kolekcji.powStopnia.ToString & _ "</powStopnia>")
Dim st As New StopienFazaZPrawej st = wsk_kolekcji
PrintLine(1, " <Faza>" & st.Faza.ToString & "</Faza>") PrintLine(1, "</StopienFazaZPrawej>")
End If Next
PrintLine(1, "</Walek>") FileClose(1)
MsgBox("Zapisano do pliku: " & plik) End Sub
Private Sub ŚrednicaStopniaToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles ŚrednicaStopniaToolStripMenuItem.Click mode = TrybPracy.SrednicaStopnia
End Sub
Private Sub DługośćStopniaToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles DługośćStopniaToolStripMenuItem.Click mode = TrybPracy.DlugoscStopnia
End Sub End Class
-- * --
Diagram UML
1Rysunek 1. Diagram klas
1 Uwaga, w wersji Visual Studio Community 2017– brak możliwości uzyskania Diagramu klas (uwaga z dn.2017.12.03)