Una forma universal de personalizar la apariencia de una aplicaci贸n WinForms (usando el ejemplo de FAQ.Net)

Introduccion


Despu茅s de publicar el primer art铆culo sobre mi aplicaci贸n FAQ.Net (programa de notas de Windows) , aparecieron los primeros usuarios que desear铆an desarrollar a煤n m谩s su programa de notas.

Para aumentar el inter茅s de los usuarios, surgi贸 una idea para aumentar su atractivo ajustando el color y la fuente.

Requisitos para personalizar la apariencia de la aplicaci贸n


  1. almacenar y cargar propiedades de componentes individuales en un archivo XML
  2. el usuario debe tener una herramienta simple para personalizar la apariencia
  3. la lista de componentes personalizados debe expandirse de manera muy simple (en una l铆nea de c贸digo)
  4. Al cambiar el valor de una propiedad, el usuario debe ver inmediatamente los cambios en el formulario
  5. deber铆a haber un bot贸n de cancelaci贸n que le permitir谩 revertir todos los cambios

Resultado del trabajo


Ventana de apariencia:



Configuraci贸n de apariencia antes y despu茅s:



Para resolver el problema es necesario


  1. use el componente PropertyGridEx para mostrar y cambiar las propiedades del componente
  2. cree una clase CustomDesignControl para la comodidad de almacenar propiedades en XML
  3. crear un formulario MainForm, en el que cambiaremos la apariencia
  4. cree un formulario AppSettingsForm, en el que personalizaremos la apariencia de MainForm
  5. cree la clase SettingsXml para facilitar el trabajo con XML

La funci贸n de deshacer cambios en la apariencia


Para implementar la supresi贸n de los cambios en la apariencia (p谩rrafo 5 de los requisitos), decid铆 encontrar una forma universal de clonar las propiedades de los componentes que se crear谩n en la memoria y reemplazar los componentes mostrados.

Clonaci贸n de objetos:

public static class ControlExtensions { public static T Clone<T>(T controlToClone) where T : Control { PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); T instance = Activator.CreateInstance<T>(); RichTextBox rtb = new RichTextBox(); foreach (PropertyInfo propInfo in controlProperties) { if (propInfo.Name == "Parent") continue; if (propInfo.CanWrite) { if (propInfo.Name != "WindowTarget") { propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null); } } } return instance; } 

Copi茅 el c贸digo, elimin茅 las propiedades innecesarias que no es necesario guardar, dejando los colores y la fuente.
Despu茅s de verificar el c贸digo, las deficiencias de este m茅todo se revelaron de inmediato:

  1. se utiliza la conversi贸n de cualquier control a la clase Control, lo que significa que la mitad de las propiedades se pueden perder (por ejemplo, el componente DataGridView se hereda de la clase Control, pero tiene su propio conjunto adicional de propiedades)
  2. Al clonar un componente, algunas propiedades (por ejemplo: el color de la fuente dentro de la celda DataGridView) no se clonan, sino que crean enlaces al componente clonado (quiz谩s esto se deba a que la propiedad se usa con sus propiedades internas y deben manejarse de alguna manera diferente).

Comenz贸 a experimentar en el segundo punto, para lograr la clonaci贸n de propiedades.
Para hacer esto, cree un objeto del tipo deseado con el nuevo operador.

 DataGridView dgvClone = new DataGridView(); 

En vano, el componente no pudo revertir los cambios.

Luego intent茅 crear la propiedad en s铆 con el nuevo operador y establecer el valor utilizando el m茅todo SetValue:

 propInfo.SetValue(_controls[i], propInfo.GetValue(_controlsBeforeChange[i], null), null); 

Y este m茅todo no dio resultado. Cuando un valor de propiedad cambia en un componente, se actualiza autom谩ticamente en el componente clonado.

Ya no busqu茅 otros m茅todos e hice que el cambio volviera simplemente reiniciando la aplicaci贸n con la capacidad de guardar el documento de trabajo o cancelar el reinicio. Esto permiti贸 ahorrar significativamente la memoria de la aplicaci贸n, ya que no es necesario crear clones de objetos.

Ejemplo de aplicaci贸n con personalizaci贸n de apariencia


Por si acaso, he preparado un c贸digo listo para usar en el que todos pueden verificar y posiblemente refinar la funci贸n de cancelar los cambios en la apariencia sin reiniciar la aplicaci贸n y contarnos el problema en los comentarios.
Es necesario asegurarse de que cuando hace clic en el bot贸n "AutoTest", el componente DataGridView tiene un fondo gris y la fuente de las celdas es peque帽a.



Descargue la aplicaci贸n de Windows FAQ.Net (gratis):

(x64) yadi.sk/d/sq3g4NOD3Zt7ZY
(x86) yadi.sk/d/NKXeyUWH3Zt8PQ

Grupo VK
C贸digo fuente FAQ.Net

Conclusi贸n


Espero que en muchas aplicaciones WinForms, gracias a este art铆culo, el usuario final tenga la oportunidad de personalizar la interfaz a su gusto y color.

Source: https://habr.com/ru/post/474104/


All Articles