Tengo este código para guardar y recuperar datos en XML.
Siempre me dicen que use getters y setters.
La forma que me enseñaron es antigua y nada que ver con ahora.
Por ejemplo.
using System.Xml;
namespace Guardar_y_cargar_datos_en_archivo.xml_.NET_7._0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Guarda los datos introducidos a parte de crear el archivo "miXML.xml".
private void button_Guardar_Click(object sender, EventArgs e)
{
XmlWriter w = XmlWriter.Create(@"archivo.xml");
w.WriteStartElement("MiInfo");
w.WriteElementString("TextBox", textBox1.Text);
w
.WriteElementString("CheckBox", checkBox1
.Checked.ToString()); w
.WriteElementString("radioButton1_Luz_ON", radioButton1
.Checked.ToString()); w
.WriteElementString("radioButton2_Luz_OFF", radioButton2
.Checked.ToString()); w.WriteEndElement();
w.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
XmlReader r = XmlReader.Create("archivo.xml");
r.ReadStartElement("MiInfo");
textBox1.Text = r.ReadElementContentAsString();
checkBox1
.Checked = Convert
.ToBoolean(r
.ReadElementContentAsString()); radioButton1
.Checked = Convert
.ToBoolean(r
.ReadElementContentAsString()); radioButton2
.Checked = Convert
.ToBoolean(r
.ReadElementContentAsString()); r.ReadEndElement();
r.Close();
}
catch (Exception)
{
//
}
}
}
}
Por supuesto, me funciona como me han enseñado.
El archivo es este que se queda guardado.
<?xml version="1.0" encoding="utf-8"?>
<MiInfo>
<TextBox>Hola amigo.</TextBox>
<CheckBox>True</CheckBox>
<radioButton1_Luz_ON>False</radioButton1_Luz_ON>
<radioButton2_Luz_OFF>True</radioButton2_Luz_OFF>
</MiInfo>
Entonces.
¿Cuál es la mejor manera de programarlo?
Saludos.
Por que no usar json ? si quieres modernizarte, puedes usar : SettingsProvider.net (https://github.com/JakeGinnivan/SettingsProvider.net) es el que uso en todas mis apps , es realmente bueno.
Si todavía quieres usar XML, puedes buscar algún snippet aquí : https://foro.elhacker.net/net/indice_de_la_libreria_de_snippets_para_vbnet-t485444.0.html (https://foro.elhacker.net/net/indice_de_la_libreria_de_snippets_para_vbnet-t485444.0.html) y puedes convertir de VB a C# usando : https://converter.telerik.com (https://converter.telerik.com)
La consulta que realizas se puede interpretar de varias formas. ¿Cual es exactamente el aspecto que buscas mejorar de ese código?. Utilizar directamente el método getter/setter de una o varias propiedades para controlar de forma eventual el cómo y el cuando guardar cierta configuración del usuario, eso podría no suponer mejor estructuración del código, ni tampoco mejora alguna con respecto a la utilización de la clase
XmlWriter para llevar a cabo esa tarea.
En cualquier caso, no lo harías utilizando directamente la clase
XmlReader para escribir elementos, sino utilizando los métodos de serialización destinados a convertir objetos en sus respectivos valores serializables, mediante la clase
XmlSerializer:
- learn.microsoft.com - Clase XmlSerializer (https://learn.microsoft.com/es-es/dotnet/api/system.xml.serialization.xmlserializer?view=net-7.0)
- learn.microsoft.com - Uso de Visual C# para serializar un objeto en XML (https://learn.microsoft.com/es-es/troubleshoot/developer/visualstudio/csharp/language-compilers/serialize-object-xml)
- learn.microsoft.com - Ejemplos de serialización XML (https://learn.microsoft.com/es-es/dotnet/standard/serialization/examples-of-xml-serialization)
En ciertos casos podrías recurrir a utilizar los correspondientes atributos de clase relacionados son la serialización de un
tipo (clase o estructura, y sus miembros definidos) en formato Xml, e implementar la interfaz
IXmlSerializable en dicho
tipo, junto al uso de la clase
XmlWriter (aquí, sí) para controlar y personalizar la serialización en formato Xml de sus miembros definidos.
Relacionado con esto, comparto aquí un ejemplo propio, de una clase por nombre "ColorString" que representa el valor de un color ARGB expresado en diferentes representaciones textuales. La clase implementa las interfaces
ISerializable e
IXmlSerializable:
https://pastebin.com/8C19nZFv (https://pastebin.com/8C19nZFv)
Nota: El código original está escrito en VB.NET; esto es una conversión automática del código a C#, probablemente haya errores de sintaxis en la consersión, y en cualquier caso NO es un código funcional (faltan referencias a otros miembros que no he añadido), es solo un ejemplo. Puedes encontrar otros ejemplos más reducidos y funcionales empezando por este:
- learn.microsoft.com - Interfaz IXmlSerializable (https://learn.microsoft.com/es-es/dotnet/api/system.xml.serialization.ixmlserializable?view=net-7.0)
O quizás al mencionar los métodos getters/setters más bien te estés refiriendo a la estructura '
Settings' que se encarga de crear código autogenerado con las propiedades que especifiques (en la pestaña "Settings" de las propiedades de tu proyecto .NET 7.0) a través del archivo "app.config" para administrar la configuración de la aplicación.
Lo cierto es que, a menos que tengas alguna razón justificable por la cual prefieras guardar la configuración en formato Xml (o en json, o en binario, me es indiferente) '
Settings' es lo que deberías usar para guardar la configuración del usuario:
- learn.microsoft.com - Introducción a la configuración de la aplicación (https://learn.microsoft.com/es-es/dotnet/desktop/winforms/advanced/application-settings-overview)
- learn.microsoft.com - Administración de la configuración de la aplicación (.NET) (https://learn.microsoft.com/es-es/visualstudio/ide/managing-application-settings-dotnet)
- learn.microsoft.com - Utilizar valores de configuración de aplicación y de usuario (https://learn.microsoft.com/es-es/dotnet/desktop/winforms/advanced/using-application-settings-and-user-settings)
PD: Esta característica está disponible desde que surgió .NET 2.0; En caso de que esto sea a lo que te estuvieses refiriendo, decir que hasta ahora estabas usando "la forma antigua" con Xml no sería muy excusable por parte de quien te haya enseñado esa forma :xD, pero tampoco por parte tuya.
Por que no usar json ? si quieres modernizarte, puedes usar : SettingsProvider.net (https://github.com/JakeGinnivan/SettingsProvider.net) es el que uso en todas mis apps , es realmente bueno.
No lo conocía. ¡Lo probaré a ver que tal!.
Ya que estamos hablando de formas para administrar la configuración del usuario, me gustaría aportar otra alternativa diferente de utilizar JSON para llevar a cabo esa función:
- Jot - a .NET library for state persistence (https://github.com/anakic/Jot)
Cita del autor:
"
Con Jot, solo necesita declarar qué propiedades de qué objetos desea rastrear y cuándo conservar y aplicar los datos."
Esto implica que no tenemos que escribir ningún código adicional para obtener ni asignar directamente los valores de la configuración. Eso se realiza de forma abstracta, sofistacadamente.
Es muy versatil y, además, ofrece simplicidad de uso mediante el patrón de diseño de interfaz fluida (
Fluent interface) que nos permite encadenar varias sentencias en pocas líneas para controlar y condicionar, con belleza y precisión, el funcionamiento y el comportamiento de carga y guardado de los valores de la configuración, pudiendo asignar nombres de eventos en los que se ha de guardar un valor de la configuración, o condiciones especiales para no hacerlo, entre otras cosas, y aislando prácticamente toda esta lógica del código fuente de la interfaz de usuario.
Muchas gracias a los dos, muy buena info. ;-)
Ya que estamos, lo he hecho con archivos de txt en el cual a nadie le interesa pero funciona.
namespace Guardar_y_cargar_datos_en_archivo.txt_.NET_7._0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
CargarControles();
}
void GuardarCrontoles()
{
string archivoDeTexto = "";
int numero = 0;
foreach (Control control in this.Controls)
{
continue;
else if (control
is TextBox
) archivoDeTexto += (numero++).ToString() + ": " + ((TextBox)control).Text + "\n";
else if (control
is CheckBox
) archivoDeTexto
+= (numero
++).ToString() + ": " + ((CheckBox
)control
).Checked + "\n"; else if (control
is RadioButton
) archivoDeTexto
+= (numero
++).ToString() + ": " + ((RadioButton
)control
).Checked + "\n"; else if (control
is GroupBox
) foreach (Control ctrl in ((GroupBox)control).Controls)
archivoDeTexto += (numero++).ToString() + ": " + ((TextBox)ctrl).Text + "\n";
else if (ctrl
is CheckBox
) archivoDeTexto += (numero++).ToString() + ": " + ((CheckBox)ctrl).Text + "\n";
else if (ctrl
is RadioButton
) archivoDeTexto += (numero++).ToString() + ": " + ((RadioButton)ctrl).Text + "\n";
}
// Guardar archivo de texto en Controles.txt.
File.WriteAllText("Controles.txt", archivoDeTexto);
}
void CargarControles()
{
int numero = 0;
string[] lineas;
if (File.Exists("Controles.txt"))
lineas = File.ReadAllLines("Controles.txt");
else
return;
foreach (Control control in this.Controls)
{
continue;
else if (control
is TextBox
) ((TextBox)control).Text = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0));
else if (control
is CheckBox
) ((CheckBox
)control
).Checked = lineas
[numero
++].Substring(3 + (numero
>= 10 ? 1 : 0)) == "True" ? true : false; else if (control
is RadioButton
) ((RadioButton
)control
).Checked = lineas
[numero
++].Substring(3 + (numero
>= 10 ? 1 : 0)) == "True" ? true : false; else if (control
is GroupBox
) foreach (Control ctrl in ((GroupBox)control).Controls)
((TextBox)ctrl).Text = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0));
else if (ctrl
is CheckBox
) ((CheckBox
)ctrl
).Checked = lineas
[numero
++].Substring(3 + (numero
>= 10 ? 1 : 0)) == "True" ? true : false; else if (ctrl
is RadioButton
) ((RadioButton
)ctrl
).Checked = lineas
[numero
++].Substring(3 + (numero
>= 10 ? 1 : 0)) == "True" ? true : false; }
}
private void button_Guardar_Click(object sender, EventArgs e)
{
GuardarCrontoles();
}
}
}
Y como dice arriba el compañero. ¿Por qué no json?
Pues también funciona.
using System.Text.Json;
namespace Guardar_y_cargar_datos_en_archivo.json_.NET_7._0___02
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
class MiInfo
{
public string? TextBox { get; set; }
public bool CheckBox { get; set; }
public bool RadioButton1_Luz { get; set; }
public bool RadioButton2_Luz { get; set; }
}
// Guardar datos en el archivo Ejemplo.json.
void GuardarDatos()
{
{
TextBox = textBox1.Text,
RadioButton1_Luz
= radioButton1
.Checked,
RadioButton2_Luz
= radioButton2
.Checked };
// Guardar con espacios en blanco el archivo .json.
var opciones
= new JsonSerializerOptions
{ WriteIndented
= true }; string serializado = JsonSerializer.Serialize(miInfo, opciones);
// Crear archivo Ejemplo.json.
File.WriteAllText(@"Ejemplo.json", serializado);
}
// Cargar datos en el archivo Ejemplo.json.
void CargarDatos()
{
// ¿Existe el archivo Ejemplo.json?
// if (File.Exists(@"Ejemplo.json") == true)
if (File.Exists(@"Ejemplo.json"))
{
// Sí. Lee el archivo completo.
string serializado = File.ReadAllText(@"Ejemplo.json");
MiInfo? miInfo = JsonSerializer.Deserialize<MiInfo>(serializado);
// ¿Es distinto a nulo?
if (miInfo != null)
{
// Sí. Lee los datos del archivo Ejemplo.json y los carga
// en sus componentes indicados.
textBox1.Text = miInfo.TextBox;
checkBox1
.Checked = miInfo
.CheckBox; radioButton1
.Checked = miInfo
.RadioButton1_Luz; radioButton2
.Checked = miInfo
.RadioButton2_Luz; }
}
}
private void button_Guardar_Click(object sender, EventArgs e)
{
GuardarDatos();
}
private void Form1_Load(object sender, EventArgs e)
{
CargarDatos();
}
}
}
Contenido del json.
{
"TextBox": "Hola amigo.",
"CheckBox": false,
"RadioButton1_Luz": false,
"RadioButton2_Luz": true
}
Salu2. :D