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 ModuleDiseñ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 ClassDiseñ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 ClassY eso es todo 🙂
