Probleem met het lezen van een XML bestand

Status
Niet open voor verdere reacties.

The Mighty Atom

Terugkerende gebruiker
Lid geworden
22 mei 2008
Berichten
1.380
Ik heb het volgende formulier gemaakt:

read_write_xml.jpg


De gebruiker klikt op de Add knop en een OpenFileDialog verschijnt waarmee de gebruiken bestanden kan selecteren en openen.
Deze bestanden verschijnen dan in de listbox.

Wanneer de gebruiker dan op Write klikt, wordt er een XML bestand geschreven.
Het XML bestand ziet er dan zo uit:
Code:
<List>
  <Item>C:\file1.txt</Item>
  <Item>C:\file2.txt</Item>
  <Item>C:\file3.txt</Item>
</List>

De code voor het schrijven van het XML bestand is als volgt:

Code:
  'Create a new XML Text Writer
        Dim WriteCompilatorSettings As New XmlTextWriter(Application.StartupPath & "\settings.xml", Nothing)

        'Set formatting
        WriteCompilatorSettings.Formatting = Formatting.Indented

        'Write the first element
        WriteCompilatorSettings.WriteStartElement("List")

        'Write the keyvalues under the last created element
        For Each Item In ListBox1.Items
            WriteCompilatorSettings.WriteElementString("Item", Item)
        Next

        'Close the XML Text Writer
        WriteCompilatorSettings.Close()



Als de gebruiker het programma afsluiten en weer opstart, en daarna op de Read knop klikt, wil ik dat diezelfde listbox items uit het XML bestand worden gelezen en teruggeplaatst worden in de listbox.

Dit lukt mij echter niet. Het schrijven lukt wel, maar ik heb zo'n idee dat de syntax van de listbox items beter kan, waardoor het lezen en terugplaatsen wel zou kunnen lukken.

Dit is de code onder de Read button:

Code:
        'Create a new XML Text Reader
        Dim ReadCompilatorSettings As New XmlTextReader(Application.StartupPath & "\settings.xml")

        'Read the first element
        ReadCompilatorSettings.ReadStartElement("List")

        For Each Item As String In ReadCompilatorSettings.ReadString
            lb1.Items.Add(ReadCompilatorSettings.ReadElementString(Item))

        Next

        'Close the XML Text Reader
        ReadCompilatorSettings.Close()

Wat doe ik hier fout?


Ik wil dit uiteindelijk gaan gebruiken om de settings van mn applicatie te bewaren. Ik heb tot nu toe het Windows Register maar ik lees steeds meer dat XML DÉ manier is om applicatie settings mee te bewaren.

Wie kan mij helpen?
 
Laatst bewerkt:
Een paar kleine aanpassingen zijn nodig om dit te kunnen.

Code:
Imports System.Xml


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ListBox1.Items.Add("test1")
        ListBox1.Items.Add("test2")
        ListBox1.Items.Add("test3")

    End Sub

    Private Sub Read()
[B]        ListBox1.Items.Clear()

        'Create a new XML Text Reader
        Dim XML As New XmlDocument
        XML.Load("c:\settings.xml")

        Dim SSN As XmlNode = XML.SelectSingleNode("/List")


        For Each Item As XmlNode In SSN
            ListBox1.Items.Add(Item.InnerText)
        Next[/B]

    End Sub



    Private Sub Write()
        'Create a new XML Text Writer
        Dim WriteCompilatorSettings As New XmlTextWriter("c:\settings.xml", [B]System.Text.Encoding.UTF8[/B])

        'Set formatting
        WriteCompilatorSettings.Formatting = Formatting.Indented


        [B]WriteCompilatorSettings.WriteStartDocument()[/B]

        'Write the first element
        WriteCompilatorSettings.WriteStartElement("List")

        'Write the keyvalues under the last created element
        For Each Item In ListBox1.Items
            WriteCompilatorSettings.WriteElementString("Item", Item)
        Next

        [B]WriteCompilatorSettings.WriteEndElement()[/B]
        [B]WriteCompilatorSettings.WriteEndDocument()[/B]

        'Close the XML Text Writer
        WriteCompilatorSettings.Close()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Write()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Read()
    End Sub
 
Dank! Dat werkt prima. Nu ik je code zo bekijk, denk ik van: teehee, is dat het? :P


Ik moet nog één soort property opslaan en lezen, namelijk de backcolor van een button.

Ik heb deze code voor het scrijven:
Code:
        WriteCompilatorSettings.WriteElementString("color", _
        Button1.BackColor.R & " " & Button1.BackColor.G & " " & Button1.BackColor.B)

Dit werkt, alleen heb ik zo'n idee dat het makkelijker kan (kortere code regel, minder text), maar wel in RGB formaat, zoals:
R G B of:
R, G, B of:
R-G-B of:
R:G:B
Wat maar het makkelijkst is.


Voor het lezen heb deze code:
Code:
Button1.BackColor = ReadCompilatorSettings.ReadElementString

Ik had kunnen weten dat dit nooit gaat werken, omdat het geen string is. Hoewel RGB in textvorm wel een string is, dus klopt het dat ik wat extra eh... woorden moet toevoegen aan die regel om te vertellen dat de RGB waarden in het XML bestand de backcolor van de button1 moeten worden?

Er staat me iets van bij dat ik CStr of CType moet gebruiken... Ik heb alleen moeite de juiste syntax te vinden...
Zou je mij hier ook mee kunnen helpen, Pizara?
 
Er bestaat een makkelijkere methode voor.

System.Drawing.Colors kent ook een .toARGB() en .fromARGB functie (Integer)

Ook krijgt xml nu een ander hoofdelement omdat je geen 2 hoofdelementen in een xml kan hebben en je die niet in je [Items] wil opslaan moet deze in een apart element [Settings].

Ik heb alle veranderingen voor je in 'Vet' gezet

Je code komt er dan zo uit te zien :

Code:
Imports System.Xml


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ListBox1.Items.Add("test1")
        ListBox1.Items.Add("test2")
        ListBox1.Items.Add("test3")

    End Sub

    Private Sub Read()
        ListBox1.Items.Clear()

        'Create a new XML Text Reader
        Dim XML As New XmlDocument
        XML.Load("c:\settings.xml")

[B]        Dim SSN As XmlNode = XML.SelectSingleNode("/XML/List")[/B]


        For Each Item As XmlNode In SSN
            ListBox1.Items.Add(Item.InnerText)
        Next

[B]
            Dim Setting As XmlNode = XML.SelectSingleNode("XML/Settings")
            Button1.BackColor = Color.FromArgb(CInt(Setting.InnerText))
[/B]

    End Sub



    Private Sub Write()
        'Create a new XML Text Writer
        Dim WriteCompilatorSettings As New XmlTextWriter("c:\settings.xml", System.Text.Encoding.UTF8)

        'Set formatting
        WriteCompilatorSettings.Formatting = Formatting.Indented


        WriteCompilatorSettings.WriteStartDocument()

[B]        WriteCompilatorSettings.WriteStartElement("XML")[/B]

        WriteCompilatorSettings.WriteStartElement("List")

        'Write the keyvalues under the last created element
        For Each Item In ListBox1.Items
            WriteCompilatorSettings.WriteElementString("Item", Item)
        Next

        WriteCompilatorSettings.WriteEndElement()

[B]        WriteCompilatorSettings.WriteStartElement("Settings")
        WriteCompilatorSettings.WriteString(Button1.BackColor.ToArgb)
        WriteCompilatorSettings.WriteEndElement()

        WriteCompilatorSettings.WriteEndElement()[/B]

        WriteCompilatorSettings.WriteEndDocument()

        'Close the XML Text Writer
        WriteCompilatorSettings.Close()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Write()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Read()
    End Sub

End Class

je XML zo :

HTML:
<?xml version="1.0" encoding="utf-8"?>
<XML>
  <List>
    <Item>test1</Item>
    <Item>test2</Item>
    <Item>test3</Item>
  </List>
  <Settings>-16755485</Settings>
</XML>

Je zal je XML eerst even moeten opslaan voordat je m kan lezen uiteraard.
 
Bedankt man, ook dat werkt prima.
CInt vertaald de RGB value naar een Integer, zodat de backcolor property het kan begrijpen. Klopt dat? Zo ja, dan heb je me wat nieuws geleerd. :)


Nog één ding, dit is alleen maar een vraag:

Ik heb op mijn form een aantal listbox en een aantal button controls.

Ik moet dus voor elke listbox en button een New XmlDocument en een XmlNode declareren.
Kan het ook met 1 XmlDocument en 1 XmlNode voor alle listbox en button controls? Anders heb je zoveel Dims...
 
Nee de toARGB() vertaald m naar een integer

fromARGB() moet dus ook gevuld worden met een integer. En sinds je uit de XML een string hebt gelezen moet je die CInt (Converten naar een INTeger)

fromARGB(CInt(XMLStringWaarde))

snappie ??

En op antwoord van je vraag zou ik zeggen maak van de Read() en Write() een sub met opties.

voorbeeld :

Code:
    Private Sub Read(ByVal Filename As String, ByVal Listbox As ListBox, ByVal Button As Button, ByVal LoadList As String, ByVal LoadSettings As String)
        Listbox.Items.Clear()

        'Create a new XML Text Reader
        Dim XML As New XmlDocument
        XML.Load(Filename)

        Dim SSN As XmlNode = XML.SelectSingleNode(LoadList)

        For Each Item As XmlNode In SSN
            Listbox.Items.Add(Item.InnerText)
        Next

        Dim Setting As XmlNode = XML.SelectSingleNode(LoadSettings)
        Button.BackColor = Color.FromArgb(CInt(Setting.InnerText))

    End Sub

Die kan je dan zo bijvoorbeeld aanroepen :

Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Read("c:\settings.xml", ListBox1, Button1, "/XML/List", "/XML/Settings")
    End Sub

dan kan je die code gewoon gebruiken zo vaak je wilt.
 
Ik heb vanmorgen je vraag nog eens goed doorgelezen.. En ik denk dat ik hem nu begrijp.
Je wilt 1 xml document, en een korte routine om te lezen én te schrijven.

Code:
Imports System.Xml


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For Each ListboxControl In Controls
            If ListboxControl.GetType.ToString = "System.Windows.Forms.ListBox" Then
                ListboxControl.Items.Add(ListboxControl.Name & "_Item1")
                ListboxControl.Items.Add(ListboxControl.Name & "_Item2")
                ListboxControl.Items.Add(ListboxControl.Name & "_Item3")
            End If
        Next

    End Sub

    Private Sub Read()

        Dim XML As New XmlDocument
        XML.Load("c:\settings.xml")

        For Each Control In Controls


            If Control.GetType.ToString = "System.Windows.Forms.ListBox" Then

                Control.Items.Clear()

                Dim SSN As XmlNode = XML.SelectSingleNode("XML/ " & Control.Name)

                For Each Item As XmlNode In SSN
                    Control.Items.Add(Item.InnerText)
                Next
            End If

            If Control.GetType.ToString = "System.Windows.Forms.Button" Then
                Dim Setting As XmlNode = XML.SelectSingleNode("XML/BackColor" & Control.Name)
                Control.BackColor = Color.FromArgb(CInt(Setting.InnerText))
            End If

        Next


    End Sub



    Private Sub Write()

        Dim WriteCompilatorSettings As New XmlTextWriter("c:\settings.xml", System.Text.Encoding.UTF8)

        WriteCompilatorSettings.Formatting = Formatting.Indented


        WriteCompilatorSettings.WriteStartDocument()

        WriteCompilatorSettings.WriteStartElement("XML")


        For Each Control In Controls


            If Control.GetType.ToString = "System.Windows.Forms.ListBox" Then

                WriteCompilatorSettings.WriteStartElement(Control.Name)

                For Each Item In Control.Items
                    WriteCompilatorSettings.WriteElementString("Item", Item)
                Next

                WriteCompilatorSettings.WriteEndElement()

            End If

            If Control.GetType.ToString = "System.Windows.Forms.Button" Then
                WriteCompilatorSettings.WriteStartElement("BackColor" & Control.Name)
                WriteCompilatorSettings.WriteString(Button1.BackColor.ToArgb)
                WriteCompilatorSettings.WriteEndElement()
            End If

        Next
                WriteCompilatorSettings.WriteEndElement()
        WriteCompilatorSettings.WriteEndDocument()

        WriteCompilatorSettings.Close()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Write()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Read()
    End Sub

End Class

HTML:
<?xml version="1.0" encoding="utf-8"?>
<XML>
  <BackColorButton6>-1250856</BackColorButton6>
  <BackColorButton5>-1250856</BackColorButton5>
  <BackColorButton4>-1250856</BackColorButton4>
  <BackColorButton3>-1250856</BackColorButton3>
  <BackColorButton2>-1250856</BackColorButton2>
  <BackColorButton1>-1250856</BackColorButton1>
  <ListBox6>
    <Item>ListBox6_Item1</Item>
    <Item>ListBox6_Item2</Item>
    <Item>ListBox6_Item3</Item>
  </ListBox6>
  <ListBox5>
    <Item>ListBox5_Item1</Item>
    <Item>ListBox5_Item2</Item>
    <Item>ListBox5_Item3</Item>
  </ListBox5>
  <ListBox4>
    <Item>ListBox4_Item1</Item>
    <Item>ListBox4_Item2</Item>
    <Item>ListBox4_Item3</Item>
  </ListBox4>
  <ListBox3>
    <Item>ListBox3_Item1</Item>
    <Item>ListBox3_Item2</Item>
    <Item>ListBox3_Item3</Item>
  </ListBox3>
  <ListBox2>
    <Item>ListBox2_Item1</Item>
    <Item>ListBox2_Item2</Item>
    <Item>ListBox2_Item3</Item>
  </ListBox2>
  <ListBox1>
    <Item>ListBox1_Item1</Item>
    <Item>ListBox1_Item2</Item>
    <Item>ListBox1_Item3</Item>
  </ListBox1>
</XML>

kijk hier even naar dan. (de xml wel eerst even opslaan)..

begrijp ik het zo goed?:cool:
 
Laatst bewerkt:
ff offtopic

@ Pizara: lukt die achtergrond kleur veranderen bij jou? mij lukt het niet om de bgcolor van controls in te stellen op een fromARGB(). Het rare is dat die wel een gewone kleur aanneemt, en dat het bij foreground colors wel gaat :confused:
 
Werkt bij mij prima ...

Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        CheckedListBox1.BackColor = Color.FromArgb(CInt(Button1.Text))
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        CheckedListBox1.BackColor = Color.FromArgb(CInt(Button2.Text))
    End Sub

    Private Sub Form1_Load_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Button1.Text = CheckedListBox1.BackColor.ToArgb
        Button2.Text = "-16755485" 'blauw
    End Sub
End Class
 
Laatst bewerkt:
Hmmm, ik krijg het toch niet echt voor elkaar.

Het lezen en schrijven van de BackColor properties en de inhoud van ListBoxes werkt prima.

Maar ik heb een probleem met het lezen van CheckBoxes, TextBoxes en ComboBoxes.

Het wegschrijven van de Checked property voor een checkbox gaat zo:

Code:
Write.WriteElementString("cb1", cb1.Checked)
                                         |              |
                                         |              |--- de checkbox waar het om gaat
                                         |
                                         |--- de naam van het element <cb1>...</cb1>


Nou dacht in de eerste instantie dat het lezen ervan op dezelfde manier ging, wel zo:

Code:
Read.WriteElementString("cb1", cb1.Checked)
Andersom werkt ook niet:
Code:
Read.WriteElementString(cb1.Checked, "cb1")

Helaas werkt dit zo niet. Ik zou graag per checkbox willen aangeven waar het zn checked property kan lezen. Dat wil zegen: z'n eigen element.

Mijn oom heeft eens de code bekeken die ik van jouw (Pizara) heb gekregen, en hij zegt dat dit:

vcb1.Checked = ReadCompilatorSettings.ReadElementString[/code]

Niet de juiste manier is. Hij voreg zich ag waar cb1 nou zn checked property vandaan haalt.

Wat denk jij?
 
Laatst bewerkt:
de waarde van de checkbox.checked wegschrijven lukt dus wel...

nogmaals , je schrijft het weg als een string waarde. Dus als je een boolean probeert te lezen moet je de string wel converteren.


Code:
Dim cb As String = CheckBox1.Checked.ToString()

Lees de waarde van Checkbox1.Checked uit en zet dat in 'cb'

Code:
CheckBox1.Checked = CBool(cb)

Converteer de waarde van 'cb' naar een Boolean en zet deze als Checkbox1.Checked.
 
Ohja,

Code:
vcb1.Checked = ReadCompilatorSettings.ReadElementString

komt niet in mijn gestuurde code voor hoor?
 
de waarde van de checkbox.checked wegschrijven lukt dus wel...

nogmaals , je schrijft het weg als een string waarde. Dus als je een boolean probeert te lezen moet je de string wel converteren.


Code:
Dim cb As String = CheckBox1.Checked.ToString()

Lees de waarde van Checkbox1.Checked uit en zet dat in 'cb'

Code:
CheckBox1.Checked = CBool(cb)

Converteer de waarde van 'cb' naar een Boolean en zet deze als Checkbox1.Checked.


Met de regel:
Write.WriteElementString("cb1", cb1.Checked)

word de checked property als True of False weggeschreven.



Ik moet dus voor elke checkbox gaan zitten Dimmen. Het gaat om 100+ checkbox controls.

Waarom bestaat er nou niet gewoon:

Read.ReadElementString("cb1", cb1.Checked)
Read.ReadElementString("cb2", cb2.Checked)
Read.ReadElementString("cb3", cb3.Checked)
etc...

Heel vervelend dat het niet zo kan.

Ik pruts nog ff verder...
 
Ik dacht dat je een 'aantal' control properties wilde opslaan. Maar het gaat hier over honderden. Die kan je beter in je resources opslaan. Die zijn daar voor bedoelt eigenlijk.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan