[Infraestructura] - Archivo INI. Guarda los datos de posición de un Formulario

Descripción general:

Código para copiar y pegar e incluirlo en los formularios de una aplicación. Lo que hace es guardar los valores de posición y tamaño del formulario al cerrarlo y recuperarlos al instanciarlo

Este código esta diseñado para ser copiado y pegado en todos los formularios de una aplicación.

Cuando se cierra el formulario se guardan en un fichero INI. los valores de situación, tamaño, si esta minimizado, oculto, y el valor TopMost

Cuando el formulario vuelve a usarse, se cargan esos valores del fichero INI. y se muestra con el mismo tamaño y en la misma posición que estaba cuando se cerró.


↑↑↑

Imagen de la grabación de este código en el fichero INI.

Aspecto del fichero INI generado

Aspecto del fichero INI generado

Código VB.Net (V 7.0)


#Region "Eventos Load / Closing [Versión - 2023-10-12]" 

    Private Sub MainWindow_Initialized(sender As Object, e As System.EventArgs) Handles Me.Initialized 
        '--------------------------------------------------------- 
        ' Otras inicializaciones 
        Call InicializacionCamposFormulario() 
        '--------------------------------------------------------- 
        ' Leer datos del fichero Ini 
        Call LeerDatosVentanaDeIni() 
    End Sub 

    Private Sub MainWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing 
        '--------------------------------------------------------- 
        ' grabar datos en el fichero Ini 
        Call GuardarDatosVentanaEnIni() 
        '--------------------------------------------------------- 
        ' destruir los objetos internos empleados en este form 
        ' FALTA POR ESCRIBIR 
        '----------------------------------------------------- 
        ' 
    End Sub 

    ''' <summary> 
    '''  Carga los cuadro de texto con la información que muestra este formulario 
    '''  Se tiene que llamar desde el evento [Initialized] 
    '''  No es obligatorio 
    ''' </summary> 
    Private Sub InicializacionCamposFormulario() 
        ' en este form no se hace nada 
    End Sub 

#End Region 

#Region "Funciones para Guardar / leer datos en fichero Ini [Versión - 2023-10-12]" 
    '------------------------------------------------ 
    ' Apunte táctico 
    '----------------------------------------------- 
    '   el nombre del ensamblado --> System.Reflection.MethodBase.GetCurrentMethod.Module.Name 
    '   el nombre de la clase -----> System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name 
    '   el nombre de la función ---> System.Reflection.MethodBase.GetCurrentMethod.Name 

    Private Const CADENA_WIN_LEFT As String = "Left" 
    Private Const CADENA_WIN_TOP As String = "Top" 
    Private Const CADENA_WIN_WIDTH As String = "Width" 
    Private Const CADENA_WIN_HEIGHT As String = "Height" 
    Private Const CADENA_WIN_TOP_MOST As String = "TopMost" 
    Private Const CADENA_WIN_WINDOW_STATE As String = "WindowState" 
    Private Const CADENA_WIN_WINDOW_VISIBILITY As String = "WindowsVisibility" 

    ' Valores por defecto de la posición y tamaño de la ventana 
    Private Const VALOR_WIN_LEFT As Integer = 20 
    Private Const VALOR_WIN_TOP As Integer = 20 
    Private Const VALOR_WIN_WIDTH As Integer = 460 
    Private Const VALOR_WIN_HEIGHT As Integer = 460 

    '---------------------------------------------------------- 
    ''' <summary> 
    '''    Lee  (de un fichero tipo Ini)  los valores (left, top, width, Height) de la  ventana 
    ''' </summary> 
    Private Sub LeerDatosVentanaDeIni() 
        Try 
            ' Obtener el nombre del ensamblado (sin extension) como nombre de fichero INI 
            ' Dim EnsambladoConExtension As String = System.Reflection.MethodBase.GetCurrentMethod.Module.Name 
            Dim SoloNombreEnsambladoSinExtension As String = 
                System.IO.Path.GetFileNameWithoutExtension(System.Reflection.MethodBase.GetCurrentMethod.Module.Name) 

            ' Obtener el nombre de la clase que sera el nombre de la sección. 
            ' La Sección de los valores INI que en este caso es el nombre de la clase 
            Dim SeccionIni As String = System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name 

            ' --------------------------------------- 
            ' Instanciar el objeto que maneja el fichero Ini 
            ' Observaciones: 
            ' - Si el fichero no existe se crea 
            ' - El fichero Ini se crea el directorio [ruta del ensamblado /DatosPrograma/ version 4 cifras] 
            ' - El nombre es: [Nombre del ensamblado (sin extension)  + extension INI] 
            ' --------------------------------------- 
            Using objIni As New Util.Ini.IniFile(SoloNombreEnsambladoSinExtension) 
                '-------------------------------------- 
                ' Posición del Form 
                If objIni.GetDouble(SeccionIni, CADENA_WIN_LEFT, 0D) > 0D Then 
                    If Me.WindowStartupLocation <> WindowStartupLocation.CenterOwner Then 
                        ' si el formulario se lanza [CenterOwner], me interesa que se centre, pero 
                        ' también me interesa que recuerde el tamaño que tenia la ultima vez que se cerro 
                        ' de esta forma, evito que la posición guardada del formulario lo mueva a otro sitio 
                        Me.Left = objIni.GetDouble(SeccionIni, CADENA_WIN_LEFT, 0D) 
                        Me.Top = objIni.GetDouble(SeccionIni, CADENA_WIN_TOP, 0D) 
                    End If 
                End If 
                Me.Width = objIni.GetDouble(SeccionIni, CADENA_WIN_WIDTH, 450D) 
                Me.Height = objIni.GetDouble(SeccionIni, CADENA_WIN_HEIGHT, 450D) 

                ' ---------------- 
                ' Estado TopMost 
                Me.Topmost = objIni.GetBoolean(SeccionIni, CADENA_WIN_TOP_MOST, False) 
                'Me.MenuVentanaSiempreVisible.IsChecked = My.Settings.MainWindow_TopMost 
                ' ---------------- 
                ' WindowState 
                ' ¡¡ Bug 2017/01/30 !! Problemas al leer. 
                ' CType, espera recibir un numero para hacer la conversion de la enumeración System.Windows.WindowStat 
                Me.WindowState = CType(objIni.GetInt32(SeccionIni, CADENA_WIN_WINDOW_STATE, 0), System.Windows.WindowState) 

                ' ---------------- 
                'Visibility Enumeración 
                'Collapsed   2 
                'No mostrar el elemento y no reservar espacio para él en el diseño. 
                'Hidden  1 
                'No mostrar el elemento, pero reservar espacio para el elemento en el diseño. 
                'Visible 0 
                'Mostrar el elemento. 
                Me.Visibility = CType(objIni.GetInt32(SeccionIni, CADENA_WIN_WINDOW_VISIBILITY, 0), System.Windows.Visibility) 

                ' ------------------------------------------- 
                ' Otras variables del form 
                'ControlDatosMailFicheros.LoadMemento() 

            End Using 

        Catch ex As System.Exception 
            Dim mensajeError As String 
            Using sw As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture) 
                sw.WriteLine("----") 
                sw.WriteLine("{0,-16} [{1}]", "Fecha local ", DateTime.Now.ToString("F", System.Globalization.CultureInfo.CurrentCulture)) 
                sw.WriteLine("ERROR {0} > {1} > {2}", 
                                          System.Reflection.MethodBase.GetCurrentMethod.Module.Name, 
                                          System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name, 
                                          System.Reflection.MethodBase.GetCurrentMethod.Name) 

                sw.WriteLine("Problemas durante el proceso de Lectura de datos de 'INI' ") 
                sw.WriteLine("----") 
                sw.WriteLine("Mensaje de error del sistema:") 

                If ex Is Nothing Then 
                    sw.WriteLine("Problema, el valor de la excepción recibida es Null") 
                Else 
                    If ex.GetType Is Nothing Then 
                        sw.WriteLine("Problema, el valor de la excepción [ex.GetType] recibida es Null") 
                    Else 
                        sw.WriteLine("GetType: [{0}]", ex.GetType.ToString) 
                    End If 
                    ' 
                    sw.WriteLine("Message: [{0}]", ex.Message) 
                End If 
                sw.WriteLine("/ Eof") 
                sw.Flush() 
                mensajeError = sw.ToString 
            End Using 
            ' Disparar el error 
            Throw New Exception(mensajeError, ex) 
            ' /FIN del error 

        End Try 
        ' / FIN  Leer los datos de la configuración 
        ' --------------------------------------------------- 
    End Sub 

    '---------------------------------------------------------- 
    ''' <summary> 
    '''    Guarda (en un fichero tipo Ini)  los valores (left, top, width, Height) de la  ventana 
    ''' </summary> 
    Private Sub GuardarDatosVentanaEnIni() 
        ' --------------------------------------------------- 
        Try 
            ' Obtener el nombre del ensamblado (sin extension) para usarlo como nombre de fichero INI 
            ' Dim EnsambladoConExtension As String = System.Reflection.MethodBase.GetCurrentMethod.Module.Name 
            Dim SoloNombreEnsambladoSinExtension As String = 
                System.IO.Path.GetFileNameWithoutExtension(System.Reflection.MethodBase.GetCurrentMethod.Module.Name) 

            ' Obtener el nombre de la clase que sera el nombre de la sección. 
            ' La Sección de los valores INI que en este caso es el nombre de la clase 
            Dim SeccionIni As String = System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name 

            ' --------------------------------------- 
            ' Instanciar el objeto que maneja el fichero Ini 
            ' Observaciones: 
            ' - Si el fichero no existe se crea 
            ' - El fichero Ini se crea el directorio [ruta del ensamblado /DatosPrograma/ version 4 cifras] 
            ' - El nombre es: [Nombre del ensamblado (sin extension)  + extension INI] 
            ' --------------------------------------- 
            Using objIni As New Util.Ini.IniFile(SoloNombreEnsambladoSinExtension) 
                '--------------------------------------- 
                ' Posición del Form 
                '--------------------------------------- 
                '--------------------------------------- 
                If Me.WindowState = WindowState.Normal Then 
                    ' El form está en posición normal, guardar todos los datos 
                    objIni.WriteValue(SeccionIni, CADENA_WIN_LEFT, Me.Left) 
                    objIni.WriteValue(SeccionIni, CADENA_WIN_TOP, Me.Top) 
                    objIni.WriteValue(SeccionIni, CADENA_WIN_WIDTH, Me.Width) 
                    objIni.WriteValue(SeccionIni, CADENA_WIN_HEIGHT, Me.Height) 
                Else 
                    '---------------------------------------------------------------- 
                    ' Si el formulario no está en modo normal 
                    ' es decir, esta minimizado, o maximizado, 
                    ' guardar los datos de la posición que tenía 
                    ' antes de minimizar o maximizar 

                    '---------------------------------------------------------------- 
                    '---------------------------------------------------------------- 
                    ' Bug 2023/10/12 (DIA DEL PILAR) 
                    ' Si la ventana esta minimizada y no ha estado nunca visible 
                    ' por ejemplo oculta con un NotifyIcon, [RestoreBounds] devuelve un valor infinito 
                    ' positivo o negativo (aun no se cuando ocurre cada valor) 
                    ' pero lo que hago es interceptarlo y grabar un valor coherente 
                    '---------------------------------------------------------------- 
                    ' Código refactorizado 
                    'objIni.WriteValue(SeccionIni, CADENA_WIN_LEFT,   Me.RestoreBounds.Left) 
                    'objIni.WriteValue(SeccionIni, CADENA_WIN_TOP,    Me.RestoreBounds.Top) 
                    'objIni.WriteValue(SeccionIni, CADENA_WIN_WIDTH,  Me.RestoreBounds.Width) 
                    'objIni.WriteValue(SeccionIni, CADENA_WIN_HEIGHT, Me.RestoreBounds.Height) 
                    ' ------------------------------------------------------------ 

                    If Double.IsPositiveInfinity(Me.RestoreBounds.Left) = True OrElse 
                        Double.IsNegativeInfinity(Me.RestoreBounds.Left) = True Then 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_LEFT, VALOR_WIN_LEFT) 
                    Else 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_LEFT, Me.RestoreBounds.Left) 
                    End If 

                    If Double.IsPositiveInfinity(Me.RestoreBounds.Top) = True OrElse 
                        Double.IsNegativeInfinity(Me.RestoreBounds.Top) = True Then 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_TOP, VALOR_WIN_TOP) 
                    Else 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_TOP, Me.RestoreBounds.Top) 
                    End If 

                    If Double.IsPositiveInfinity(Me.RestoreBounds.Width) = True OrElse 
                        Double.IsNegativeInfinity(Me.RestoreBounds.Width) = True Then 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_WIDTH, VALOR_WIN_WIDTH) 
                    Else 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_WIDTH, Me.RestoreBounds.Width) 
                    End If 

                    If Double.IsPositiveInfinity(Me.RestoreBounds.Height) = True OrElse 
                        Double.IsNegativeInfinity(Me.RestoreBounds.Height) = True Then 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_HEIGHT, VALOR_WIN_HEIGHT) 
                    Else 
                        objIni.WriteValue(SeccionIni, CADENA_WIN_HEIGHT, Me.RestoreBounds.Height) 
                    End If 

                End If 

                ' ------------------------------------------- 
                ' Estado TopMost 
                objIni.WriteValue(SeccionIni, CADENA_WIN_TOP_MOST, Me.Topmost) 
                'Me.MenuVentanaSiempreVisible.IsChecked = My.Settings.MainWindow_TopMost 
                ' --------------- 
                ' WindowState 
                objIni.WriteValue(SeccionIni, CADENA_WIN_WINDOW_STATE, Me.WindowState.ToString) 

                ' --------------- 
                ' WindowState 
                objIni.WriteValue(SeccionIni, CADENA_WIN_WINDOW_VISIBILITY, Me.Visibility.ToString) 

                ' ------------------------------------------- 
                ' Otras variables del form 
                ' 
                'ControlDatosMailFicheros.SaveMemento() 
                ' ------------------------------------------- 
                objIni.Flush() 
            End Using 

        Catch ex As System.Exception 
            Dim mensajeError As String 
            Using sw As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture) 
                sw.WriteLine("----") 
                sw.WriteLine("{0,-16} [{1}]", "Fecha local ", DateTime.Now.ToString("F", System.Globalization.CultureInfo.CurrentCulture)) 
                sw.WriteLine("ERROR {0} > {1} > {2}", 
                                          System.Reflection.MethodBase.GetCurrentMethod.Module.Name, 
                                          System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name, 
                                          System.Reflection.MethodBase.GetCurrentMethod.Name) 

                sw.WriteLine("Problemas durante el proceso de escritura de datos de 'INI' ") 
                sw.WriteLine("----") 
                sw.WriteLine("Mensaje de error del sistema:") 

                If ex Is Nothing Then 
                    sw.WriteLine("Problema, el valor de la excepción recibida es Null") 
                Else 
                    If ex.GetType Is Nothing Then 
                        sw.WriteLine("Problema, el valor de la excepción [ex.GetType] recibida es Null") 
                    Else 
                        sw.WriteLine("GetType: [{0}]", ex.GetType.ToString) 
                    End If 
                    ' 
                    sw.WriteLine("Message: [{0}]", ex.Message) 
                End If 
                sw.WriteLine("/ Eof") 
                sw.Flush() 
                mensajeError = sw.ToString 
            End Using 
            ' Disparar el error 
            Throw New Exception(mensajeError, ex) 
            ' /FIN del error 

        End Try 
        ' / FIN  guardar los datos en la configuración 
        ' --------------------------------------------------- 
    End Sub 

#End Region