.net 2010 VB.NET Xml Winforms - Сохранение дочернего положения и состояния MDI - PullRequest
1 голос
/ 22 сентября 2010

Я знаю, что нечто подобное уже задавалось, но вот моя проблема.

В MDI WinForm я хочу сохранить каждую позицию и состояние дочернего окна для каждого пользователя приложения, которое отличается от пользователя, вошедшего в систему. У моего приложения есть свои пользователи; поэтому я не буду использовать пользовательские настройки, такие как my.Settings ... и т. д.

Одним из вариантов является чтение / запись непосредственно в базу данных, но мне не нравится идея получить доступ к базе данных для чего-то такого тривиального, как положение окон. Плюс в том, что я могу хранить эту информацию независимо на машине, на которой работает пользователь, где бы он ни входил, ее предпочтения будут запомнены.

Другой вариант, которому я хотел бы следовать, - использовать 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 для 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, когда закончил его сборку. Должен ли я использовать XmlWriter.Create? Горячий передать его XElement?

3) Что происходит, когда в файле Xml уже есть узел с таким же именем, я хочу перезаписать предыдущие пользовательские настройки, если они уже есть, но не добавить в файл или переписать весь файл, конечно

Спасибо.

1 Ответ

1 голос
/ 22 сентября 2010

Это может быть полезно кому-то еще:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...