IU Moderno, Temas MultiColor Aleatorio, Resaltar botón-Form Activo, WinForm, C#, VB.NET

Hola, aquí os traigo un nuevo tutorial de diseño de interfaces moderno, plano y multicolor aleatorio, con la opción de abrir un único formulario secundario en un panel, el botón se resalta al abrir un formulario y este se mantiene activo hasta cerrar el formulario. Ademas mostraremos el titulo de formulario, aplicar el color actual al formulario secundario y agregar un único botón para cerrar cualquier formulario hijo.

Adicionalmente, crearemos la función de arrastrar el formulario, cerrar, minimizar, maximizar (Sin tapar la barra de tareas) y restaurar el formulario.

Bien, empecemos con el tutorial.

Clase ThemeColor

  • Primeramente creamos una clase estática de nombre ThemeColor.
  • Declaramos propiedades para el color primario y secundario.
  • Creamos una lista de cadenas (List<string>) para almacenar la lista de colores que deseamos usar, en formato html.
  • Finalmente creamos un método para cambiar el brillo del color, este método es muy útil si queremos oscurecer o aclarar un color, prácticamente cambiar la tonalidad de un color determinado.
    public static class ThemeColor
    {

        public static Color PrimaryColor { get; set; }
        public static Color SecondaryColor { get; set; }
        public static List<string> ColorList = new List<string>() { "#3F51B5",
                                                                    "#009688",
                                                                    "#FF5722",
                                                                    "#607D8B",
                                                                    "#FF9800",
                                                                    "#9C27B0",
                                                                    "#2196F3",
                                                                    "#EA676C",
                                                                    "#E41A4A",
                                                                    "#5978BB",
                                                                    "#018790",
                                                                    "#0E3441",
                                                                    "#00B0AD",
                                                                    "#721D47",
                                                                    "#EA4833",
                                                                    "#EF937E",
                                                                    "#F37521",
                                                                    "#A12059",
                                                                    "#126881",
                                                                    "#8BC240",
                                                                    "#364D5B",
                                                                    "#C7DC5B",
                                                                    "#0094BC",
                                                                    "#E4126B",
                                                                    "#43B76E",
                                                                    "#7BCFE9",
                                                                    "#B71C46"};
        public static Color ChangeColorBrightness(Color color, double correctionFactor)
        {
            double red = color.R;
            double green = color.G;
            double blue = color.B;

            //If correction factor is less than 0, darken color.
            if (correctionFactor < 0)
            {
                correctionFactor = 1 + correctionFactor;
                red *= correctionFactor;
                green *= correctionFactor;
                blue *= correctionFactor;
            }
            //If correction factor is greater than zero, lighten color.
            else
            {
                red = (255 - red) * correctionFactor + red;
                green = (255 - green) * correctionFactor + green;
                blue = (255 - blue) * correctionFactor + blue;
            }

            return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
        }

    }
Module ThemeColor
    Public Property PrimaryColor As Color
    Public Property SecondaryColor As Color
    Public ColorList As List(Of String) = New List(Of String)() From {
        "#3F51B5",
        "#009688",
        "#FF5722",
        "#607D8B",
        "#FF9800",
        "#9C27B0",
        "#2196F3",
        "#EA676C",
        "#E41A4A",
        "#5978BB",
        "#018790",
        "#0E3441",
        "#00B0AD",
        "#721D47",
        "#EA4833",
        "#EF937E",
        "#F37521",
        "#A12059",
        "#126881",
        "#8BC240",
        "#364D5B",
        "#C7DC5B",
        "#0094BC",
        "#E4126B",
        "#43B76E",
        "#7BCFE9",
        "#B71C46"
    }

    Function ChangeColorBrightness(color As Color, correctionFactor As Double) As Color
        Dim red As Double = color.R
        Dim green As Double = color.G
        Dim blue As Double = color.B
'If correction factor is less than 0, darken color.'
        If correctionFactor < 0 Then
            correctionFactor = 1 + correctionFactor
            red *= correctionFactor
            green *= correctionFactor
            blue *= correctionFactor
'If correction factor is greater than zero, lighten color.'
        Else
            red = (255 - red) * correctionFactor + red
            green = (255 - green) * correctionFactor + green
            blue = (255 - blue) * correctionFactor + blue
        End If
        Return Color.FromArgb(color.A, CByte(red), CByte(green), CByte(blue))
    End Function

End Module

Diseño Formulario de Menú Principal

  • Diseñamos el formulario de menú principal, puedes hacerlo a tu manera o de la siguiente manera:
  • Agregamos un panel para el menú, elegimos un color (RGB=51, 51, 76), y los acoplamos al lado izquierdo (Dock=Left).
  • En el panel menú, agregamos los botones necesarios, y le damos el estilo que queramos. Opcionalmente agregamos un panel en la parte superior para el logo
  • Agregamos un panel para la barra de titulo, en ella, agregamos un label para el titulo, un botón hacia el lado izquierdo(Dock=Left) para cerrar el formulario hijo activo(abierto). También agregamos botones para minimizar, maximizar y cerrar el formulario principal.
  • Finalmente agregamos un panel para contener/alojar los formularios secundarios (Hijos), opcionalemente en ella, agregamos un logo(picturebox).

Código Formulario de Menú Principal

  • Una vez diseñado el formulario, pasemos a codificar, clic derecho -> ver código.
  • Declaramos campos de forma privada para el boton actual, un generador de números aleatorios, un indice temporal y un formulario activo.
  • Inicializamos el campo random y algunos elementos de diseño en el constructor (FormMainMenu()).
  • Importamos la librería nativa user32.dll para arrastrar el formulario (ReleaseCapture() / SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam)).
  • Creamos un método para seleccionar el color de tema (SelectThemeColor()).
  • Creamos un método para activar/resaltar el botón y tema (ActivateButton(object btnSender)).
  • Creamos un método para desactivar el botón (DisableButton()).
  • Creamos un método para abrir formularios secundarios en el panel contenedor (OpenChildForm(Form childForm, object btnSender)).
  • Creamos un metodo para reiniciar los valores por defecto del formulario (Reset()).
  • Creamos los eventos click de los botones, en ello, invocamos el método abrir formulario hijo (btnProducts_Click…..).
  • Creamos el evento MouseDown del panel barra de titulo para arrastrar el formulario, en ella invocamos los metodos de la librería nativa user32.dll (panelTitleBar_MouseDown(object sender, MouseEventArgs e))
  • Finalmente creamos las funciones de cerrar, minimizar y maximizar/restaurar (btnClose_Click….).
   public partial class FormMainMenu : Form
    {
        //Fields
        private Button currentButton;
        private Random random;
        private int tempIndex;
        private Form activeForm;

        //Constructor
        public FormMainMenu()
        {
            InitializeComponent();
            random = new Random();
            btnCloseChildForm.Visible = false;
            this.Text = string.Empty;
            this.ControlBox = false;
            this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
        }
        [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
        private extern static void ReleaseCapture();

        [DllImport("user32.DLL", EntryPoint = "SendMessage")]
        private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam);

        //Methods
        private Color SelectThemeColor()
        {
            int index = random.Next(ThemeColor.ColorList.Count);
            while (tempIndex == index)
            {
                index = random.Next(ThemeColor.ColorList.Count);
            }
            tempIndex = index;
            string color = ThemeColor.ColorList[index];
            return ColorTranslator.FromHtml(color);
        }

        private void ActivateButton(object btnSender)
        {
            if (btnSender != null)
            {
                if (currentButton != (Button)btnSender)
                {
                    DisableButton();
                    Color color = SelectThemeColor();
                    currentButton = (Button)btnSender;
                    currentButton.BackColor = color;
                    currentButton.ForeColor = Color.White;
                    currentButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 12.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    panelTitleBar.BackColor = color;
                    panelLogo.BackColor = ThemeColor.ChangeColorBrightness(color, -0.3);
                    ThemeColor.PrimaryColor = color;
                    ThemeColor.SecondaryColor= ThemeColor.ChangeColorBrightness(color, -0.3);
                    btnCloseChildForm.Visible = true;
                }
            }
        }

        private void DisableButton()
        {
            foreach (Control previousBtn in panelMenu.Controls)
            {
                if (previousBtn.GetType() == typeof(Button))
                {
                    previousBtn.BackColor = Color.FromArgb(51, 51, 76);
                    previousBtn.ForeColor = Color.Gainsboro;
                    previousBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                }
            }
        }

        private void OpenChildForm(Form childForm, object btnSender)
        {
            if (activeForm != null)
                activeForm.Close();
            ActivateButton(btnSender);
            activeForm = childForm;
            childForm.TopLevel = false;
            childForm.FormBorderStyle = FormBorderStyle.None;
            childForm.Dock = DockStyle.Fill;
            this.panelDesktopPane.Controls.Add(childForm);
            this.panelDesktopPane.Tag = childForm;
            childForm.BringToFront();
            childForm.Show();
            lblTitle.Text = childForm.Text;

        }

        private void btnProducts_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormProduct(), sender);
        }

        private void btnOrders_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormOrders(), sender);
        }

        private void btnCustomers_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormCustomers(), sender);
        }

        private void btnReport_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormReporting(), sender);
        }

        private void btnNotifications_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormNotifications(), sender);
        }

        private void btnSetting_Click(object sender, EventArgs e)
        {
            OpenChildForm(new Forms.FormSetting(), sender);
        }

        private void btnCloseChildForm_Click(object sender, EventArgs e)
        {
            if (activeForm != null)
                activeForm.Close();
            Reset();
        }

        private void Reset()
        {
            DisableButton();
            lblTitle.Text = "HOME";
            panelTitleBar.BackColor = Color.FromArgb(0, 150, 136);
            panelLogo.BackColor = Color.FromArgb(39, 39, 58);
            currentButton = null;
            btnCloseChildForm.Visible = false;
        }

        private void panelTitleBar_MouseDown(object sender, MouseEventArgs e)
        {
            ReleaseCapture();
            SendMessage(this.Handle, 0x112, 0xf012, 0);
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnMaximize_Click(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Normal)
                this.WindowState = FormWindowState.Maximized;
            else
                this.WindowState = FormWindowState.Normal;
        }

        private void bntMinimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }
    }
Imports System.Runtime.InteropServices

Public Class Form1

    'FIELDS'
    Private currentButton As Button
    Private random As Random
    Private tempIndex As Integer
    Private activeForm As Form

    'CONSTRUCTOR'
    Public Sub New()
        InitializeComponent()
        random = New Random()
        currentButton = New Button()
        Me.btnCloseChildForm.Visible = False
        Me.Text = String.Empty
        Me.ControlBox = False
        Me.MaximizedBounds = Screen.FromHandle(Me.Handle).WorkingArea
    End Sub

    'METHODS'
    Private Function SelectThemeColor() As Color
        Dim index As Integer = random.[Next](ThemeColor.ColorList.Count)
        While tempIndex = index
            index = random.[Next](ThemeColor.ColorList.Count)
        End While
        tempIndex = index
        Dim color As String = ThemeColor.ColorList(index)
        Return ColorTranslator.FromHtml(color)
    End Function

    Private Sub ActivateButton(btnSender As Object)
        If btnSender IsNot Nothing Then
            If currentButton.Name <> CType(btnSender, Button).Name Then
                DisableButton()
                Dim color As Color = SelectThemeColor()
                currentButton = CType(btnSender, Button)
                currentButton.BackColor = color
                currentButton.ForeColor = Color.White
                currentButton.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (CByte((0))))
                panelTitleBar.BackColor = color
                panelLogo.BackColor = ThemeColor.ChangeColorBrightness(color, -0.3)
                ThemeColor.PrimaryColor = color
                ThemeColor.SecondaryColor = ThemeColor.ChangeColorBrightness(color, -0.3)
                btnCloseChildForm.Visible = True
            End If
        End If
    End Sub

    Private Sub DisableButton()
        For Each previousBtn As Control In panelMenu.Controls

            If previousBtn.[GetType]() = GetType(Button) Then
                previousBtn.BackColor = Color.FromArgb(51, 51, 76)
                previousBtn.ForeColor = Color.Gainsboro
                previousBtn.Font = New System.Drawing.Font("Microsoft Sans Serif", 10.0F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (CByte((0))))
            End If
        Next
    End Sub

    Private Sub OpenChildForm(childForm As Form, btnSender As Object)
        If activeForm IsNot Nothing Then activeForm.Close()
        ActivateButton(btnSender)
        activeForm = childForm
        childForm.TopLevel = False
        childForm.FormBorderStyle = FormBorderStyle.None
        childForm.Dock = DockStyle.Fill
        Me.panelDesktopPane.Controls.Add(childForm)
        Me.panelDesktopPane.Tag = childForm
        childForm.BringToFront()
        childForm.Show()
        lblTitle.Text = childForm.Text
    End Sub

    Private Sub btnCloseChildForm_Click(sender As Object, e As EventArgs) Handles btnCloseChildForm.Click
        If (Not (activeForm) Is Nothing) Then
            activeForm.Close()
        End If
        Reset()
    End Sub

    Private Sub Reset()
        DisableButton()
        lblTitle.Text = "HOME"
        panelTitleBar.BackColor = Color.FromArgb(0, 150, 136)
        panelLogo.BackColor = Color.FromArgb(39, 39, 58)
        currentButton = New Button()
        btnCloseChildForm.Visible = False
    End Sub

    'DRAG FORM'
    <DllImport("user32.DLL", EntryPoint:="ReleaseCapture")>
    Private Shared Sub ReleaseCapture()
    End Sub
    <DllImport("user32.DLL", EntryPoint:="SendMessage")>
    Private Shared Sub SendMessage(hWnd As IntPtr, wMsg As Integer, wParam As Integer, lParam As Integer)
    End Sub

    Private Sub panelTitleBar_MouseDown(sender As Object, e As MouseEventArgs) Handles panelTitleBar.MouseDown
        ReleaseCapture()
        SendMessage(Me.Handle, &H112&, &HF012&, 0)
    End Sub

    'EVENTS
    Private Sub btnProducts_Click(sender As Object, e As EventArgs) Handles btnProducts.Click
        OpenChildForm(New FormProducts(), sender)
    End Sub

    Private Sub btnOrders_Click(sender As Object, e As EventArgs) Handles btnOrders.Click
        OpenChildForm(New FormOrders(), sender)
    End Sub

    Private Sub btnCustomers_Click(sender As Object, e As EventArgs) Handles btnCustomers.Click
        OpenChildForm(New FormCustomers(), sender)
    End Sub

    Private Sub btnReport_Click(sender As Object, e As EventArgs) Handles btnReport.Click
        OpenChildForm(New FormReports(), sender)
    End Sub

    Private Sub btnNotifications_Click(sender As Object, e As EventArgs) Handles btnNotifications.Click
        OpenChildForm(New FormNotifications(), sender)
    End Sub

    Private Sub btnSetting_Click(sender As Object, e As EventArgs) Handles btnSetting.Click
        OpenChildForm(New FormSetting(), sender)
    End Sub

    'CLOSE, MAXIMIZE, MINIMIZE FORM MAIN'

    Private Sub bntMinimize_Click(sender As Object, e As EventArgs) Handles bntMinimize.Click
        Me.WindowState = FormWindowState.Minimized
    End Sub

    Private Sub btnMaximize_Click(sender As Object, e As EventArgs) Handles btnMaximize.Click

        If (WindowState = FormWindowState.Normal) Then
            Me.WindowState = FormWindowState.Maximized
        Else
            Me.WindowState = FormWindowState.Normal
        End If
    End Sub

    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Application.Exit()
    End Sub

End Class

Diseño Formularios Secundarios (Hijo)

  • Agregamos y diseñamos formularios secundarios.

Código Formularios Secundarios (Hijo)

  • Creamos un método para cargar el color actual (tema) y aplicar al formulario secundario (LoadTheme()).
  • Invocamos el método anterior en el evento load o constructor.
        private void FormOrders_Load(object sender, EventArgs e)
        {
            LoadTheme();
        }

        private void LoadTheme()
        {
            foreach (Control btns in this.Controls)
            {
                if (btns.GetType() == typeof(Button))
                {
                    Button btn = (Button)btns;
                    btn.BackColor = ThemeColor.PrimaryColor;
                    btn.ForeColor = Color.White;
                    btn.FlatAppearance.BorderColor = ThemeColor.SecondaryColor;
                }
            }
            label4.ForeColor = ThemeColor.SecondaryColor;
            label5.ForeColor = ThemeColor.PrimaryColor;
        }
Public Class FormProducts
    Private Sub FormProducts_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        LoadTheme()
    End Sub

    Private Sub LoadTheme()
        For Each btns As Control In Me.Controls

            If btns.[GetType]() = GetType(Button) Then
                Dim btn As Button = CType(btns, Button)
                btn.BackColor = ThemeColor.PrimaryColor
                btn.ForeColor = Color.White
                btn.FlatAppearance.BorderColor = ThemeColor.SecondaryColor
            End If
        Next
        label4.ForeColor = ThemeColor.SecondaryColor
        label5.ForeColor = ThemeColor.PrimaryColor
    End Sub
End Class

Y eso es todo 🙂

Ver Video Tutorial

Descargas

4 comentarios en «IU Moderno, Temas MultiColor Aleatorio, Resaltar botón-Form Activo, WinForm, C#, VB.NET»

  1. Hola !
    Tus tutoriales son increíbles. realmente te hace querer entrar en la programación de computadoras y un día convertirte en un experto eminente como tú.

    No pasará mucho tiempo antes de que repita el ejercicio después de tu publicación en Youtube. Todo funciona bien Pero tuve un problema en los formularios secundarios con PictureBoxes. la imagen se niega a mostrarse correctamente, sin embargo, el modo de visualización está en ImageLayout.Stretch.

    Gracias.

  2. Excelente, he notado que en youtube he visto varios videos sobre diseño de interfaces para ver detalles puntuales, pero veo que la mayoria de los que me han gustado son de rjcodeadvance. Ahora que encontré tu página y blog, voy a explorarla por que me gusta el diseño que le pones.

    Este en particular me gusta, pero más para implementar un selector de tema por el usuario.

    Saludos!

  3. You are great at UI design! i was exactly looking for the «accordion» nav bar, or outlook style.

    Can i download the source code for this project somewhere?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *