代码之家  ›  专栏  ›  技术社区  ›  vulkanino

.NET 2010 VB.NET XML WinForms-持久化MDI子位置和状态

  •  1
  • vulkanino  · 技术社区  · 14 年前

    我知道有人问过类似的问题,但这是我的问题。

    在MDI WinForm中,我希望按应用程序用户保存每个子窗口的位置和状态,这与登录的Windows用户不同。我的应用程序有自己的用户;所以我不会使用像我的.settings这样的用户设置…等。

    一种选择是直接读/写数据库,但是我不喜欢为了一些像Windows位置这样简单的东西访问数据库。另外,我可以通过用户工作的机器独立地存储这些信息,无论她登录到哪里,她的偏好都会被记住。

    我想遵循的另一种选择是,使用XML将这些信息存储在用户计算机上本地的一个文件中。结构可以是这样的:

    <form name="form name">
        <Top>120</Top>
                <Left>100</Left>
                <State>0</State>
        </form>
    
        <form name="another form">
            <Top>120</Top>
                <Left>120</Left>
                <State>1</State>
        </form>
    

    我很难理解这是怎么做到的;也许使用linq-to-xml?我发现我可以写一些简单的东西

    Dim formPos As XElement = _
        <User><%= My.Application.connectedUser.id %>
                    <form1>
                        <Top>120</Top>
                        <Left>100</Left>
                        <State>0</State>
                    </form1>
    
                    <form2>
                        <Top>120</Top>
                        <Left>100</Left>
                        <State>0</State>
                    </form2>
             </User>
    

    但是:

    1)如何常规地填充XML选项:我想要

    <User id="1"> 
    

    而不是 <User><%= My.Application.connectedUser.id %> 也就是说 <User>1

    2)Xelement构建完成后,如何编写Xelement。我应该用一个 XmlWriter.Create ?想把它送过去吗?

    3)当XML文件中已经有一个同名的节点时会发生什么情况,我希望覆盖以前的用户设置(如果它们已经存在),但不要附加到文件中,也不要重写整个文件。

    谢谢。

    1 回复  |  直到 14 年前
        1
  •  1
  •   vulkanino    14 年前

    它可能对其他人有用:

    Public Shared Sub SaveWindowPosition(ByVal formToSave As Form, ByVal userid As Integer)
    
            Dim formPosLeft As Integer = formToSave.Location.X
            Dim formPosTop As Integer = formToSave.Location.Y
            Dim formDimWidth As Integer = formToSave.Width
            Dim formDimHeight As Integer = formToSave.Height
            Dim formState As Integer = formToSave.WindowState
            Dim formName As String = formToSave.Name
    
    
            '   Apri il file dove memorizzo le posizioni delle varie form
            '
            Dim xdoc As XDocument
            Try
                xdoc = XDocument.Load(FILE_NAME)
            Catch ex As Exception
                '   Non trovato, va creato uno nuovo
                '
                Dim settings As New XmlWriterSettings()
                settings.Indent = True
                Dim writer As XmlWriter = XmlWriter.Create(FILE_NAME, settings)
    
                writer.WriteStartDocument()
                writer.WriteStartElement("Root")
    
                writer.WriteEndElement()
                writer.WriteEndDocument()
                writer.Close()
    
                Try
                    xdoc = XDocument.Load(FILE_NAME)
                Catch ex2 As Exception
                    '   Nemmeno questa volta è riuscito ad aprire il file, basta
                    '
                    Exit Sub
                End Try
            End Try
    
            Dim elementRoot As XElement = xdoc.Element("Root")
    
            '   Cerca l'utente corrente (per id)
            '
            Dim cercaUtente As IEnumerable(Of XElement) =
                From c In elementRoot.Elements("Utente") Where c.Attribute("id").Value = CStr(userid)
            Select c
            If cercaUtente.Count = 0 Then
                '   Utente non trovato, crealo con tutti gli altri elementi
                '
                Dim xutente As XElement =
                    <Utente id=<%= userid %>>
                        <Form name=<%= formName %>>
                            <Position top=<%= formPosTop %> left=<%= formPosLeft %> width=<%= formDimWidth %> height=<%= formDimHeight %> state=<%= formState %>></Position>
                        </Form>
                    </Utente>
    
                elementRoot.Add(xutente)
            Else
    
                '   Utente trovato, cerca la form 
                '
                Dim cercaForm As IEnumerable(Of XElement) =
                    From c In cercaUtente.Elements("Form") Where c.Attribute("name").Value = formName
                Select c
    
                If cercaForm.Count = 0 Then
                    '   Form non trovata, creala
                    '
                    Dim formPos As XElement = _
                        <Form name=<%= formName %>>
                            <Position top=<%= formPosTop %> left=<%= formPosLeft %> width=<%= formDimWidth %> height=<%= formDimHeight %> state=<%= formState %>></Position>
                        </Form>
    
                    cercaUtente.ElementAt(0).Add(formPos)
                Else
                    '   Trovato tutto, sostituisci gli attributi
                    '
                    Dim position As XElement = cercaForm.ElementAt(0).Element("Position")
                    position.ReplaceAttributes(
                        {
                            New XAttribute("top", formPosTop),
                            New XAttribute("left", formPosLeft),
                            New XAttribute("width", formDimWidth),
                            New XAttribute("height", formDimHeight),
                            New XAttribute("state", formState)
                        })
    
                End If
            End If
    
            '   Salva il file
            '
            xdoc.Save(FILE_NAME)
        End Sub
    
    
    
    
    
    
    Public Shared Sub SetWindowPosition(ByVal formToPosition As Form, ByVal userid As Integer)
    
            formToPosition.SuspendLayout()
    
            Dim xdoc As XDocument
            Try
                xdoc = XDocument.Load(FILE_NAME)
            Catch ex As Exception
                '   File non trovato, nulla da fare
                '
                Exit Sub
            End Try
    
            Dim elementRoot As XElement = xdoc.Element("Root")
    
            '   Cerca l'utente corrente (per id)
            '
            Dim cercaUtente As IEnumerable(Of XElement) =
                From c In elementRoot.Elements("Utente") Where c.Attribute("id").Value = CStr(userid)
            Select c
            If cercaUtente.Count = 0 Then Exit Sub
    
            Dim cercaForm As IEnumerable(Of XElement) =
                    From c In cercaUtente.Elements("Form") Where c.Attribute("name").Value = formToPosition.Name
                Select c
    
            If cercaForm.Count = 0 Then Exit Sub
    
            '   Preleva tutti gli attributi
            '
            Dim position As XElement = cercaForm.ElementAt(0).Element("Position")
            Dim top As Integer = CInt(position.Attribute("top"))
            Dim left As Integer = CInt(position.Attribute("left"))
            Dim width As Integer = CInt(position.Attribute("width"))
            Dim height As Integer = CInt(position.Attribute("height"))
            Dim state As FormWindowState = CType([Enum].Parse(GetType(FormWindowState), CStr(position.Attribute("state"))), FormWindowState)
    
            '   Imposta posizione, dimensione e stato, ma solo se lo stato è normale, altrimenti ignora i valori 
            '
            formToPosition.WindowState = state
    
            If state = FormWindowState.Normal Then
                formToPosition.Location = New Point(left, top)
                formToPosition.Width = width
                formToPosition.Height = height
                formToPosition.StartPosition = FormStartPosition.Manual
            End If
    
            '   TODO: controllare che posizione e dimensioni siano NORMALI cioè che la form non vada a finire fuori dallo schermo 
    
            formToPosition.ResumeLayout(False)
        End Sub