Results 1 to 14 of 14

Thread: Save Label BackColor to XML

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Save Label BackColor to XML

    Hi All,

    I am using this code to save label information to an XML file after the label is clicked. Modifying this code, I can seem to save the label info correctly, but I am getting stuck on the loading label info back to my from labels when I run the code. I'm not even sure if this is the proper way of doing this. My modified label only contains a new backcolor and text. Near the end of my 'LoadLabels', I am also not sure what to do on the 'With labels'...

    *Note that I am referencing buttons in some parts, but this is only for Labels on my form.

    Code:
        Private Sub SaveLabels(ByVal container As Form1, ByVal filename As String)
    
            Dim xmlfile As New Xml.XmlDocument
            Dim decl As XmlDeclaration = xmlfile.CreateXmlDeclaration("1.0", "UTF-8", "yes")
            FilePathToXML = prgPath & "\schedule.xml"
    
            xmlfile.AppendChild(decl)
            Dim labelsroot As XmlElement = xmlfile.CreateElement("buttoncollection")
            xmlfile.AppendChild(labelsroot)
    
            For Each lbl As Label In Me.Controls.OfType(Of Label)()
    
                Dim labelnode As XmlElement = xmlfile.CreateElement("button")
                Dim textattr As XmlAttribute = xmlfile.CreateAttribute("text")
                Dim kolor As XmlAttribute = xmlfile.CreateAttribute("color")
    
                textattr.Value = lbl.Text
                kolor.Value = lbl.BackColor.ToArgb
    
                With labelnode.Attributes
                    .Append(textattr)
                    .Append(kolor)
                End With
    
                labelsroot.AppendChild(labelnode)
            Next
    
            xmlfile.Save(FilePathToXML)
        End Sub
    
    
        Private Sub LoadLabels(ByVal container As Form1, ByVal filename As String)
    
            FilePathToXML = prgPath & "\schedule.xml"
    
            Dim xmlfile As New XmlDocument
    
            Try
                xmlfile.Load(FilePathToXML)
            Catch ex As IOException
                MsgBox("Error Loading XML File or file does not exist!" & ex.Message, vbExclamation, "xml not found..")
    
                Dim xmlfileNew As New Xml.XmlDocument
                Dim decl As XmlDeclaration = xmlfileNew.CreateXmlDeclaration("1.0", "UTF-8", "yes")
    
                xmlfileNew.AppendChild(decl)
                Dim labelsroot As XmlElement = xmlfileNew.CreateElement("buttoncollection")
                xmlfileNew.AppendChild(labelsroot)
                xmlfileNew.Save(FilePathToXML)
                Exit Sub
            End Try
    
            Dim buttonsroot As XmlElement = DirectCast(xmlfile.SelectSingleNode("buttoncollection"), XmlElement)
    
            For Each buttonnode As XmlElement In buttonsroot.ChildNodes.OfType(Of XmlElement)()
    
                With Labels????
                    .Text = buttonnode.Attributes("text").Value
                    .ForeColor = Color.Firebrick
                    .BackColor = Color.LightGreen
                    .TextAlign = ContentAlignment.MiddleCenter
                    .Size = Size
                    .Font = New Font("Agency FB", 12, FontStyle.Regular)
                End With
            Next
    
        End Sub

  2. #2
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Save Label BackColor to XML

    Using XElement, LINQ, and embedded expressions.

    The save

    Code:
        Private Sub SaveLabels(ByVal container As Form1, ByVal filename As String)
            Dim xmlfile As XElement = <labels></labels>
            'FilePathToXML = prgPath & "\schedule.xml"
    
            For Each lbl As Label In Me.Controls.OfType(Of Label)()
                Dim labelEL As XElement
                labelEL = <label name=<%= lbl.Name %>>
                              <text><%= lbl.Text %></text>
                              <bcolor><%= lbl.BackColor.ToArgb %></bcolor>
                          </label>
                xmlfile.Add(labelEL)
            Next
    
            ' xmlfile.Save(FilePathToXML)
        End Sub
    To load

    Code:
        Private Sub LoadLabels(FilePathToXML As String)
            Dim xmlfile As XElement = XElement.Load(FilePathToXML)
            For Each lbl As Label In Me.Controls.OfType(Of Label)()
                Dim lblEL As XElement
                lblEL = (From el In xmlfile...<label>
                            Where el.@name = lbl.Name
                            Select el
                            Take 1).FirstOrDefault
                If lblEL IsNot Nothing Then
                    lbl.BackColor = Color.FromArgb(Integer.Parse(lblEL.<bcolor>.Value))
                    lbl.Text = lblEL.<text>.Value
                End If
            Next
        End Sub
    Last edited by dbasnett; Mar 23rd, 2022 at 02:16 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Re: Save Label BackColor to XML

    *Edit. I found the path was empty

    Thanks dbasnett... I tried this out and save seems to work fine. I get an error on 'LoadLabels' in line:
    Code:
    Dim xmlfile As XElement = XElement.Load(FilePathToXML)
    Error:
    Code:
    System.ArgumentNullException: 'Value cannot be null.
    Parameter name: inputUri'
    Last edited by mikeg71; Mar 23rd, 2022 at 10:16 AM.

  4. #4
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Save Label BackColor to XML

    Quote Originally Posted by mikeg71 View Post
    *Edit. I found the path was empty

    Thanks dbasnett... I tried this out and save seems to work fine. I get an error on 'LoadLabels' in line:
    Code:
    Dim xmlfile As XElement = XElement.Load(FilePathToXML)
    Error:
    Code:
    System.ArgumentNullException: 'Value cannot be null.
    Parameter name: inputUri'
    Can you post your LoadLabels please?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  5. #5
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,370

    Re: Save Label BackColor to XML

    Quote Originally Posted by mikeg71 View Post
    I am using this code to save label information to an XML file after the label is clicked. Modifying this code, I can seem to save the label info correctly, but I am getting stuck on the loading label info back to my from labels when I run the code. I'm not even sure if this is the proper way of doing this.
    There are a couple of issues I have with your approach if you are open to suggestions.
    1. I would suggest against doing something in a label click event, doing so would go against common user experience (UX). Labels should only every show text.
    2. Based on your description, it seems like you save every label anytime something is changed. I would suggest setting up a single "save" button that would persist the changes when the user clicks on the button. This would not only prevent unnecessary writes, but it would also conform to normal UX patterns.
    3. I would suggest against using XML and instead switch to JSON. XML is so 1990s.
    4. By serializing the Labels to JSON, you won't need to manually create the controls.
    5. There really is no need for the container argument in your methods, it is not being used.


    Take a look at this example:
    Code:
    Private Sub SaveLabels(filename As String)
        Dim labels = Me.Controls.OfType(Of Label)()
        Dim json = JsonConvert.SerializeObject(labels)
        IO.File.WriteAllText(filename, json)
    End Sub
    
    Private Sub LoadLabels(filename As String)
        Dim contents = IO.File.ReadAllText(filename)
        Dim labels = JsonConvert.DeserializeObject(Of IEnumerable(Of Label))(contents)
        Me.Controls.AddRange(labels)
    End Sub
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Re: Save Label BackColor to XML

    Thanks dday9.. I am always open to suggestions as it gives me more to learn from. I have not used json before and xml is still quite new to my projects. With your example, is there more to it that I would need? I get an error on the JsonConvert in both stating they are not declared.

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Re: Save Label BackColor to XML

    Quote Originally Posted by dbasnett View Post
    Can you post your LoadLabels please?
    Thanks dbasnett, this code is working fine now once I realized the path was empty.

  8. #8
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,370

    Re: Save Label BackColor to XML

    Quote Originally Posted by mikeg71 View Post
    I get an error on the JsonConvert in both stating they are not declared.
    You would need to add a reference to the Newtonsoft.Json library:
    1. In Visual Studio's menu bar (at the top of the application) click on Project > Manage NuGet Packages
    2. Click on the Browse tab in the NuGet Package Manager
    3. Search for Newtonsoft.Json
    4. Select the topmost result by James Newton-King in the left hand pane
    5. Click on Install in the right hand pane


    Now when you go to use it, you'll need to import the appropriate namespaces. I usually let Visual Studio do that for me by putting my cursor on the line that has the error from the missing import, use the shortcut key Ctrl + . (period), and then import the appropriate namespace.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Re: Save Label BackColor to XML

    thanks dday9... I did add the reference so I don't get errors there. When I ran it, I get this message:
    Code:
    Newtonsoft.Json.JsonSerializationException: 'Self referencing loop detected for property 'Owner' with type 'System.Windows.Forms.Label'. Path '[0].AccessibilityObject'.'
    It happens in the SaveLabels on this line:
    Code:
    Dim json = JsonConvert.SerializeObject(labels)

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Save Label BackColor to XML

    Before you go down the JSON path, be aware that it depends a fair amount on which version of .NET you are using. If you are using Framework, then the NewtonSoft approach is the only one you have. With .NET 5, MS included a JSON library right into .NET, so if you are using .NET 5 or 6, then NewtonSoft would not be the way to go. Instead, you'd be using the items in the System.Text.Json namespace.
    My usual boring signature: Nothing

  11. #11
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,370

    Re: Save Label BackColor to XML

    A quick search using search.brave.com led to this solution: https://stackoverflow.com/a/13549982/1920035
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Jan 2021
    Posts
    191

    Re: Save Label BackColor to XML

    Quote Originally Posted by dday9 View Post
    A quick search using search.brave.com led to this solution: https://stackoverflow.com/a/13549982/1920035
    How would I implement this? Is this C#

    Code:
    JsonConvert.SerializeObject(ResultGroups, Formatting.None,
                            new JsonSerializerSettings()
                            { 
                                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                            });

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Save Label BackColor to XML

    Yes, that's C#, but it's virtually the same as the VB. I think there would just be a With {} rather than just the {}.
    My usual boring signature: Nothing

  14. #14
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,370

    Re: Save Label BackColor to XML

    And without the semicolon.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width