Hi all,

I hope someone can help me with this because it's driving me insane.

I've spent almost two solid days trying to figure this out without much success.

What I need to do is load in an XML file (which I have working fine) but then I need to cycle through each element and extract each of the childnode values into it's own textbox so the user can then edit the values and save the edited XML file.

The XML file looks like this (it has been edited down a little)

<?xml version="1.0" standalone="yes"?>
<window>
	<id>35</id>
	<defaultcontrol>6</defaultcontrol>
	<allowoverlay>yes</allowoverlay>
	<disabletopbar>no</disabletopbar>
	<rememberLastFocusedControl>yes</rememberLastFocusedControl>
	<controls>

		<control>
			<description>BG</description>
			<type>image</type>
			<id>1</id>
			<texture>Background.png</texture>
			<width>720</width>
			<height>576</height>
		</control>

		<control>
			<description>Big text</description>
			<type>label</type>
			<id>200</id>
			<posX>355</posX>
			<posY>200</posY>
			<label>#highlightedbutton</label>
			<align>center</align>
			<font>dingbats</font>
			<textcolor>40ffffff</textcolor>
		<animation>WindowOpen</animation>
            		<animation>WindowClose</animation>
		</control>

        <import>common.videowindow.small.xml</import>		
	</controls>
</window>

Each of the 'control' elements can potentially have a different number of childnodes. which is my first problem.

Also, there can be varying numbers of 'control' elements

I sort of have an idea in my head of how to achieve what I want, but don't have the first clue on how to do it.

Bascially what I want to do is determine the number of 'control' elements (which I have done) and then create a new 'tab' for each one.

Within each individual tab I want to create a text box and a label for each 'control' childnode title (label) and value (textbox), the user will be able to then edit these values and then click a button to save the XML file.

Here's where I am with the vb.
At the moment, it loads the XML and determines how many 'control' elements there are.

Public Class Form1

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

        Me.cmbFolders.DataSource = (From folder In New IO.DirectoryInfo("C:\ProgramData\Team MediaPortal\MediaPortal\skin\").GetDirectories Select (folder.Name)).ToArray

    End Sub

    Private Sub cmbFolders_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbFolders.SelectedIndexChanged

        Dim str_SkinName As String
        Dim str_SourceFolder As String
        Dim str_CurrentSkin As String
        Dim str_FileName As String

        Dim intControlCounter As Integer

        Dim xmlDoc As New XmlDocument

        Dim teststring As String

        teststring = ""

        str_FileName = "BasicHome.xml"
        str_SourceFolder = "C:\ProgramData\Team MediaPortal\MediaPortal\skin\"
        str_SkinName = cmbFolders.SelectedValue

        str_CurrentSkin = str_SourceFolder & str_SkinName & "\" & str_FileName

        txtFilePath.Text = str_CurrentSkin

        xmlDoc.Load(str_CurrentSkin)
        intControlCounter = xmlDoc.SelectNodes("window/controls/control").Count

        txtControlNo.Text = intControlCounter

        'MsgBox(xmlDoc.OuterXml)

    End Sub

End Class

Thanks for reading through, please don't hesitate to ask if something is unclear.

Thanks
TheMightySpud

Not sure how set you are on using textboxes for your data but I think you might be better off using a datagridview since you don't have a fixed number of attributes. Here's some code using a datagridview...

Dim tmpDataGridView As DataGridView
        Dim tmpTabPage As TabPage
        Dim controlNodes As XmlNodeList = xmlDoc.SelectNodes("window/controls/control")

        'Clear tabs
        TabControl1.TabPages.Clear()
        For i = 0 To controlNodes.Count - 1
            'Create new tab
            tmpTabPage = New TabPage("Control " & i + 1)
            'Create and intialize new datagridview
            tmpDataGridView = New DataGridView
            tmpDataGridView.AllowUserToAddRows = False
            tmpDataGridView.AllowUserToDeleteRows = False
            tmpDataGridView.RowHeadersVisible = False
            tmpDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            tmpDataGridView.Dock = DockStyle.Fill
            'Add columns
            tmpDataGridView.Columns.Add("Column1", "Name")
            tmpDataGridView.Columns(0).ReadOnly = True
            tmpDataGridView.Columns.Add("Column2", "Value")
            'Add data
            tmpDataGridView.Rows.Add(controlNodes(i).ChildNodes.Count)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                tmpDataGridView.Item(0, i2).Value = controlNodes(i).ChildNodes(i2).Name
                tmpDataGridView.Item(1, i2).Value = controlNodes(i).ChildNodes(i2).InnerText
            Next
            'Add to form
            tmpTabPage.Controls.Add(tmpDataGridView)
            TabControl1.TabPages.Add(tmpTabPage)
        Next

Add a TabControl to your form called TabControl1 and put this code at the end of your sub. See how that works for you.

I want to have your children LOL.

That is fantastic, thanks. Didn't really think of using a datagrid view before but it works great.

Thanks you ever so much.

The reason I wanted to use text boxes is that some of the entried are things like images and colours and would like to add in browsing and picker capabilites later on.

Is that possible with datagrids?

TheMightySpud

All is possible with datagridview! :) Well not all, but more than most .NET controls. Gets more complicated since you're creating the dgvs dynamically at runtime, but you can handle cell clicks or doubleclicks or whatever to pop up a file browser or color picker or something.
If you're looking to actually display an image in the value column, I'm not sure how that would work out. I think to display an image in a column, the whole column has to be an image column. So then text wouldn't work in that column(for other row values). But I'm not sure.
I still think it's a better method than textboxes, but ultimately you can decide for yourself if it's got enough functionality for your images and colors.

I don't need to display the images or the colours at all, just their text equivalients (ie 005599 for colours and simply the filename for images)

TheMightySpud

Ok it should work for you then. Just have to add handlers to the datagridviews for cellbeginedit, something like

AddHandler tmpDataGridView.CellBeginEdit, AddressOf DGVCellEdit

somewhere in your controlNodes loop. And then process that in the function and if you want to, display whatever editor you want and set e.cancel=true...

Private Sub DGVCellEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs)
        Dim tmpDataGridView As DataGridView = CType(sender, DataGridView)
        If tmpDataGridView.Item(0, e.RowIndex).Value = "textcolor" Then
            'Show color dialog
            If ColorDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
                tmpDataGridView.Item(e.ColumnIndex, e.RowIndex).Value = Hex(ColorDialog1.Color.ToArgb).Substring(2)
            End If
            e.Cancel = True
        End If
    End Sub

That should give you a good start.

That's stunning......thanks for the help, I'm not going to implement it just yes as I have one more problem to solve before moving on to what is essentially cosmetic functionality. :)

What I need to do now is to be able to change the values in the grid, and then save it back out to the same xml file.

I tried being a smart alec and simply reversing your code

Private Sub btnCommit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCommit.Click


        For i = 0 To controlNodes.Count - 1
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next


        Dim file As String

        file = str_CurrentSkin
        If System.IO.File.Exists(file) = True Then
         Dim objReader As New System.IO.StreamReader(file)

        objReader.Close()
        End If

    End Sub

But surprisingly, that doesn't work.

From what I've been reading, do I need to use the XMLwriter method? or would a tweaking of the above code be enough?

Again, thanks for all the help.
TheMightySpud

Well looks like you're on the right track, but you haven't defined tmpDataGridView anywhere. You have to cycle through the datagridviews with that function, so something like this:

For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next

As far as saving the XML, that's the easy one. XmlDocument has a save function built right in. So just do

xmlDoc.Save(str_CurrentSkin)
commented: Absolutely brilliant and helpful. Thank You +1

oh sweet.....

as for not defining tmpDataGridView....I should included the whole thing. Sorry.

I've moved pretty much everything up into Public declarations........I've been told different thing about doing that, ie some bad, some good.

Public Class Form1

    Dim xmlDoc As New XmlDocument

    Dim tmpDataGridView As DataGridView
    Dim tmpTabPage As TabPage
    Dim controlNodes As XmlNodeList = xmlDoc.SelectNodes("window/controls/control")

    Dim str_SkinName As String
    Dim str_SourceFolder As String
    Dim str_CurrentSkin As String
    Dim str_FileName As String

    Dim intControlCounter As Integer

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

        Me.cmbFolders.DataSource = (From folder In New IO.DirectoryInfo("C:\ProgramData\Team MediaPortal\MediaPortal\skin\").GetDirectories Select (folder.Name)).ToArray

    End Sub

    Private Sub cmbFolders_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbFolders.SelectedIndexChanged

        str_FileName = "BasicHome.xml"
        str_SourceFolder = "C:\ProgramData\Team MediaPortal\MediaPortal\skin\"
        str_SkinName = cmbFolders.SelectedValue

        str_CurrentSkin = str_SourceFolder & str_SkinName & "\" & str_FileName

        txtFilePath.Text = str_CurrentSkin

        xmlDoc.Load(str_CurrentSkin)
        intControlCounter = xmlDoc.SelectNodes("window/controls/control").Count

        txtControlNo.Text = intControlCounter

        'MsgBox(xmlDoc.OuterXml)


        'Clear tabs
        TabControl1.TabPages.Clear()
        For i = 0 To controlNodes.Count - 1
            'Create new tab
            If i >= 9 Then
                tmpTabPage = New TabPage("Control " & i + 1)
            Else
                tmpTabPage = New TabPage("Control 0" & i + 1)
            End If

            'Create and intialize new datagridview
            tmpDataGridView = New DataGridView
            tmpDataGridView.AllowUserToAddRows = False
            tmpDataGridView.AllowUserToDeleteRows = False
            tmpDataGridView.RowHeadersVisible = True
            tmpDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            tmpDataGridView.Dock = DockStyle.Fill
            'Add columns
            tmpDataGridView.Columns.Add("Column1", "Name")
            tmpDataGridView.Columns(0).ReadOnly = True
            tmpDataGridView.Columns.Add("Column2", "Value")
            'Add data
            tmpDataGridView.Rows.Add(controlNodes(i).ChildNodes.Count)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                tmpDataGridView.Item(0, i2).Value = controlNodes(i).ChildNodes(i2).Name
                tmpDataGridView.Item(1, i2).Value = controlNodes(i).ChildNodes(i2).InnerText
            Next
            'Add to form
            tmpTabPage.Controls.Add(tmpDataGridView)
            TabControl1.TabPages.Add(tmpTabPage)
        Next

        txtPreview.Text = xmlDoc.OuterXml


    End Sub

    Private Sub btnCommit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCommit.Click


        For i = 0 To controlNodes.Count - 1
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next


        'Dim file As String

        'file = str_CurrentSkin
        'If System.IO.File.Exists(file) = True Then
        ' Dim objReader As New System.IO.StreamReader(file)

        'objReader.Close()
        'End If

    End Sub

End Class

That's the whole thing as it stands (haven't re-worked the last loop yet)

Thanks
TheMightySpud

me655321,

I just want to thank you again for all the help. I've got it all working and happy now (the basic, open, edit, save functionality anyway) thanks to you.

Hope you don't mind me picking your brains a little more as I progress with the more 'cosmetic' of features.

TheMightySpud

Hey, glad I could help out...gl with the rest of it. And yeah if you run into trouble, don't be afraid to ask.

Yes it's me again ;-)

I noticed something earlier while mucking about with drawing shapes based on the imported XML.

The fields in the datagrid aren't being updated when I change the option in the dropdown box :-/

I have a multiline textbox which shows the raw XML, and that changes whenever I choose a different option, but in the datagrid, nothing shows.

I've tried to fix it myself without any luck.

Any ideas?

Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Class Form1

    Dim xmlDoc As New XmlDocument

    Dim tmpDataGridView As DataGridView
    Dim tmpTabPage As TabPage
    Dim controlNodes As XmlNodeList = xmlDoc.SelectNodes("window/controls/control")

    Dim str_SkinName As String
    Dim str_SourceFolder As String
    Dim str_CurrentSkin As String
    Dim str_FileName As String

    Dim intControlCounter As Integer



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

        Me.cmbFolders.DataSource = (From folder In New IO.DirectoryInfo("C:\ProgramData\Team MediaPortal\MediaPortal\skin\").GetDirectories Select (folder.Name)).ToArray

    End Sub

    Private Sub cmbFolders_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbFolders.SelectedIndexChanged

        str_FileName = "BasicHome.xml"
        str_SourceFolder = "C:\ProgramData\Team MediaPortal\MediaPortal\skin\"
        str_SkinName = cmbFolders.SelectedValue

        str_CurrentSkin = str_SourceFolder & str_SkinName & "\" & str_FileName

        txtFilePath.Text = str_CurrentSkin

        xmlDoc.Load(str_CurrentSkin)
        intControlCounter = xmlDoc.SelectNodes("window/controls/control").Count

        txtControlNo.Text = intControlCounter

        'MsgBox(xmlDoc.OuterXml)

        'Clear tabs
        TabControl1.TabPages.Clear()


        For i = 0 To controlNodes.Count - 1
            'Create new tab
            If i >= 9 Then
                tmpTabPage = New TabPage("Control " & i + 1)
            Else
                tmpTabPage = New TabPage("Control 0" & i + 1)
            End If

            'Create and intialize new datagridview
            tmpDataGridView = New DataGridView
            tmpDataGridView.AllowUserToAddRows = False
            tmpDataGridView.AllowUserToDeleteRows = False
            tmpDataGridView.RowHeadersVisible = True
            tmpDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            tmpDataGridView.Dock = DockStyle.Fill
            'Add columns
            tmpDataGridView.Columns.Add("Column1", "Name")
            tmpDataGridView.Columns(0).ReadOnly = True
            tmpDataGridView.Columns.Add("Column2", "Value")
            'Add data
            tmpDataGridView.Rows.Add(controlNodes(i).ChildNodes.Count)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                tmpDataGridView.Item(0, i2).Value = controlNodes(i).ChildNodes(i2).Name
                tmpDataGridView.Item(1, i2).Value = controlNodes(i).ChildNodes(i2).InnerText
            Next
            'Add to form

            tmpTabPage.Controls.Add(tmpDataGridView)
            TabControl1.TabPages.Add(tmpTabPage)

        Next
        txtPreview.Text = xmlDoc.OuterXml

    End Sub

    Private Sub btnCommit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCommit.Click

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next

        txtPreview.Text = xmlDoc.OuterXml

        xmlDoc.Save(str_CurrentSkin)

        'Dim file As String

        'file = str_CurrentSkin
        'If System.IO.File.Exists(file) = True Then
        ' Dim objReader As New System.IO.StreamReader(file)

        'objReader.Close()
        'End If

    End Sub

    Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
        xmlDoc.Save(str_CurrentSkin)
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        MsgBox("Universal BasicHome Editor (c)2009")
    End Sub

    Private Sub HelpToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripMenuItem1.Click
        MsgBox("Not Yet Available")
    End Sub

    Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click
        'MsgBox("Working")
        'dimension variables of local scope



        Dim g As System.Drawing.Graphics
        Dim imagepen As New System.Drawing.Pen(Color.Black)
        Dim buttonpen As New System.Drawing.Pen(Color.Red)
        Dim labelpen As New System.Drawing.Pen(Color.Blue)
        Dim borderpen As New System.Drawing.Pen(Color.Green)
        Dim controlwidth As Integer
        Dim controlheight As Integer
        Dim controlposx As Integer
        Dim controlposy As Integer

        'PictureBox1.Refresh()

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1

                If tmpDataGridView.Item(0, i2).Value = "width" Then
                    controlwidth = tmpDataGridView.Item(1, i2).Value
                    controlwidth = controlwidth / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "height" Then
                    controlheight = tmpDataGridView.Item(1, i2).Value
                    controlheight = controlheight / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "posx" Then
                    controlposx = tmpDataGridView.Item(1, i2).Value
                    controlposx = controlposx / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "posy" Then
                    controlposy = tmpDataGridView.Item(1, i2).Value
                    controlposy = controlposy / 2
                End If

                'MsgBox(controlwidth)

                If tmpDataGridView.Item(1, i2).Value = "BG" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(borderpen, x:=controlposx + 4, y:=controlposy + 4, width:=controlwidth + 2, height:=controlheight + 2)
                ElseIf tmpDataGridView.Item(1, i2).Value = "image" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(imagepen, x:=controlposx + 5, y:=controlposy + 5, width:=controlwidth, height:=controlheight)
                End If

                If tmpDataGridView.Item(1, i2).Value = "button" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(buttonpen, x:=controlposx + 5, y:=controlposy + 5, width:=controlwidth, height:=controlheight)
                End If

                If tmpDataGridView.Item(1, i2).Value = "label" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(labelpen, x:=controlposx + 5, y:=controlposy + 5, width:=controlwidth, height:=controlheight)
                End If

            Next
        Next

    End Sub

End Class

Thanks
TheMightySpud

Never mind, I fixed it all by my lonesome LOL

Probably will be asking something again soon though :)

TheMightySpud

Heya once again,

Having some new issues.

I'm trying to display images inside a picture box based on information from the XML file that I've opened.

Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next

        txtPreview.Text = xmlDoc.OuterXml

        PictureBox1.Refresh()

        controlposx = 0
        controlposy = 0
        controlwidth = 0
        controlheight = 0

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1

                If tmpDataGridView.Item(0, i2).Value = "width" Then
                    controlwidth = tmpDataGridView.Item(1, i2).Value
                    controlwidth = controlwidth / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "height" Then
                    controlheight = tmpDataGridView.Item(1, i2).Value
                    controlheight = controlheight / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "posX" Or tmpDataGridView.Item(0, i2).Value = "posx" Then
                    controlposx = tmpDataGridView.Item(1, i2).Value
                    controlposx = controlposx / 2
                End If

                If tmpDataGridView.Item(0, i2).Value = "posY" Or tmpDataGridView.Item(0, i2).Value = "posy" Then
                    controlposy = tmpDataGridView.Item(1, i2).Value
                    controlposy = controlposy / 2
                End If


                If tmpDataGridView.Item(0, i2).Value = "textureFocus" Then
                    PictureBox1.Image = Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value)
                    g = PictureBox1.CreateGraphics
                    g.DrawImage((PictureBox1.Image), controlposx, controlposy, controlwidth, controlheight)

                End If


                If tmpDataGridView.Item(1, i2).Value = "button" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(buttonpen, x:=controlposx, y:=controlposy, width:=controlwidth, height:=controlheight)
                End If

                If tmpDataGridView.Item(1, i2).Value = "label" Then
                    g = PictureBox1.CreateGraphics
                    g.DrawRectangle(labelpen, x:=controlposx, y:=controlposy, width:=controlwidth, height:=controlheight)
                End If

            Next
        Next

    End Sub

I've got the code successfully displaying coloured rectangles based on position and size information, and now I'm trying to replace those rectangles with actual images.

The problem I'm having is that the code displays the images, but instead of adding them to the picture box, it replaces the previous image.

I'm sure I'm missing something in the way I'm calling the image and assigning them to the picturebox, but I can't seem to figure out a way to fix it.

Thanks
TheMightySpud

Ok, I think I get what you're trying to do. But I'm confused as to what is supposed to be the overall background image in your picturebox. In your textureFocus if, you're setting the picturebox image to the value(so changing the background) and then you're adding that same image at a smaller size to the picture. Do you just want to do this?

If tmpDataGridView.Item(0, i2).Value = "textureFocus" Then
            g = PictureBox1.CreateGraphics
            g.DrawImage(Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value), controlposx, controlposy, controlwidth, controlheight)
        End If

And then maybe initialize the picturebox at the beginning like this...

PictureBox1.Image = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)

Not sure if that's exactly what you want to do. By the way, I think it would be easier to do what you're doing with a select case...

Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
            Next
        Next

        txtPreview.Text = xmlDoc.OuterXml

        PictureBox1.Image = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)

        controlposx = 0
        controlposy = 0
        controlwidth = 0
        controlheight = 0

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                Select Case tmpDataGridView.Item(0, i2).Value
                    Case "width"
                        controlwidth = tmpDataGridView.Item(1, i2).Value
                        controlwidth = controlwidth / 2
                    Case "height"
                        controlheight = tmpDataGridView.Item(1, i2).Value
                        controlheight = controlheight / 2
                    Case "posX", "posx"
                        controlposx = tmpDataGridView.Item(1, i2).Value
                        controlposx = controlposx / 2
                    Case "posY", "posy"
                        controlposy = tmpDataGridView.Item(1, i2).Value
                        controlposy = controlposy / 2
                    Case "textureFocus"
                        g = PictureBox1.CreateGraphics
                        g.DrawImage(Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value), controlposx, controlposy, controlwidth, controlheight)
                    Case "button"
                        g = PictureBox1.CreateGraphics
                        g.DrawRectangle(buttonpen, x:=controlposx, y:=controlposy, Width:=controlwidth, Height:=controlheight)
                    Case "label"
                        g = PictureBox1.CreateGraphics
                        g.DrawRectangle(labelpen, x:=controlposx, y:=controlposy, Width:=controlwidth, Height:=controlheight)
                End Select

            Next
        Next

    End Sub

Thanks again :)

Your code really helped, I've had to futz about with it a little, but I now have it displaying exactly how I want it to. Still need to muck about with sizing/scaling a little on a couple of the elements, but so far it's looking great.

I'm including a few screenshots so you can see where I'm at with all your help :)

Next step(s) are getting the XML preview to display all neatly and readable, and getting some of the 'label' elements to display within the picturebox. I'm pretty sure it's possible with the DrawString fuctionality, just need to read up a bit :) and then dynamically creating the picture box based on the aspect ratio of the skin selected (4.3 / 16.9 etc) Should be interesting LOL.

Oh, the question of the background image, it's actually one of the <control> elements, took me a couple of hours to figure out, but I got it displaying correctly (it kept displaying 'on top' of all the other elements, which was really annoying, but really satisfying when I got it to work :))

Updated Code :

Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Class Form1

    Dim xmlDoc As New XmlDocument
    Dim tmpDataGridView As DataGridView
    Dim tmpTabPage As TabPage
    Dim controlNodes As XmlNodeList = xmlDoc.SelectNodes("window/controls/control")

    Dim str_SkinName As String
    Dim str_SourceFolder As String
    Dim str_skinFolder As String
    Dim str_CurrentSkin As String
    Dim str_FileName As String
    Dim intControlCounter As Integer

    Dim g As System.Drawing.Graphics
    Dim imagepen As New System.Drawing.Pen(Color.Black)
    Dim buttonpen As New System.Drawing.Pen(Color.Red)
    Dim labelpen As New System.Drawing.Pen(Color.Blue)
    Dim controlwidth As Integer
    Dim controlheight As Integer
    Dim controlposx As Integer
    Dim controlposy As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.cmbFolders.DataSource = (From folder In New IO.DirectoryInfo("C:\ProgramData\Team MediaPortal\MediaPortal\skin\").GetDirectories Select (folder.Name)).ToArray
    End Sub

    Private Sub cmbFolders_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbFolders.SelectedIndexChanged

        'PictureBox1.Refresh()
        PictureBox1.Image = Nothing

        str_FileName = "BasicHome.xml"
        str_SourceFolder = "C:\ProgramData\Team MediaPortal\MediaPortal\skin\"
        str_SkinName = cmbFolders.SelectedValue
        str_skinFolder = str_SourceFolder & str_SkinName
        str_CurrentSkin = str_SourceFolder & str_SkinName & "\" & str_FileName
        txtFilePath.Text = str_CurrentSkin
        xmlDoc.Load(str_CurrentSkin)
        intControlCounter = xmlDoc.SelectNodes("window/controls/control").Count
        txtControlNo.Text = intControlCounter
        controlNodes = xmlDoc.SelectNodes("window/controls/control")
        'MsgBox(xmlDoc.OuterXml)
        'Clear tabs
        TabControl1.TabPages.Clear()
        For i = 0 To controlNodes.Count - 1
            'Create new tab
            If i >= 9 Then
                tmpTabPage = New TabPage("Control " & i + 1)
            Else
                tmpTabPage = New TabPage("Control 0" & i + 1)
            End If
            'Create and intialize new datagridview
            tmpDataGridView = New DataGridView
            tmpDataGridView.AllowUserToAddRows = False
            tmpDataGridView.AllowUserToDeleteRows = False
            tmpDataGridView.RowHeadersVisible = True
            tmpDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            tmpDataGridView.Dock = DockStyle.Fill
            'Add columns
            tmpDataGridView.Columns.Add("Column1", "Name")
            tmpDataGridView.Columns(0).ReadOnly = True
            tmpDataGridView.Columns.Add("Column2", "Value")
            'Add data
            tmpDataGridView.Rows.Add(controlNodes(i).ChildNodes.Count)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                tmpDataGridView.Item(0, i2).Value = controlNodes(i).ChildNodes(i2).Name
                tmpDataGridView.Item(1, i2).Value = controlNodes(i).ChildNodes(i2).InnerText
            Next
            'Add to form
            tmpTabPage.Controls.Add(tmpDataGridView)
            TabControl1.TabPages.Add(tmpTabPage)
        Next

        txtPreview.Text = xmlDoc.OuterXml

    End Sub

    Private Sub btnCommit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCommit.Click

        xmlDoc.Save(str_CurrentSkin)

    End Sub

    Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
        xmlDoc.Save(str_CurrentSkin)
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        MsgBox("Universal BasicHome Editor (c)2009")
    End Sub

    Private Sub HelpToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripMenuItem1.Click
        MsgBox("Not Yet Available")
    End Sub

    Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1
                controlNodes(i).ChildNodes(i2).InnerText = tmpDataGridView.Item(1, i2).Value
                If tmpDataGridView.Item(1, i2).Value = "Background.png" Then
                    PictureBox1.Image = Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value)
                    g = PictureBox1.CreateGraphics
                    g.DrawImage((PictureBox1.Image), controlposx, controlposy, controlwidth, controlheight)
                End If

            Next
        Next
        PictureBox1.Refresh()

        txtPreview.Text = xmlDoc.OuterXml

        controlposx = 0
        controlposy = 0
        controlwidth = 0
        controlheight = 0

        For i = 0 To controlNodes.Count - 1
            tmpDataGridView = TabControl1.TabPages(i).Controls(0)
            For i2 = 0 To controlNodes(i).ChildNodes.Count - 1

                Select Case tmpDataGridView.Item(0, i2).Value

                    Case "width"
                        controlwidth = tmpDataGridView.Item(1, i2).Value
                        controlwidth = controlwidth / 2
                    Case "height"
                        controlheight = tmpDataGridView.Item(1, i2).Value
                        controlheight = controlheight / 2
                    Case "posX", "posx"
                        controlposx = tmpDataGridView.Item(1, i2).Value
                        controlposx = controlposx / 2
                    Case "posY", "posy"
                        controlposy = tmpDataGridView.Item(1, i2).Value
                        controlposy = controlposy / 2
                    Case "Background.png"
                        g = PictureBox1.CreateGraphics
                        g.DrawImage(Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value), controlposx, controlposy, controlwidth, controlheight)
                    Case "texture"
                        g = PictureBox1.CreateGraphics
                        g.DrawImage(Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value), controlposx, controlposy, controlwidth, controlheight)
                    Case "textureNoFocus"
                        g = PictureBox1.CreateGraphics
                        g.DrawImage(Image.FromFile(str_skinFolder & "\Media\" & tmpDataGridView.Item(1, i2).Value), controlposx, controlposy, controlwidth, controlheight)
                        'Case "label"
                        'g = PictureBox1.CreateGraphics
                        'g.DrawRectangle(labelpen, x:=controlposx, y:=controlposy, width:=controlwidth, height:=controlheight)
                End Select
            Next
        Next
    End Sub


End Class

TheMightySpud

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.