Pues eso… lo prometido es deuda y aquí tienes el código completo de cómo mostrar todos los formularios de una aplicación (ensamblado) y cómo mostrar un formulario en el segundo monitor.
Al final de todo te pongo el enlace para descargar los proyectos tanto de Visual Basic como de C#.
¡Que te aproveche!
Estas son las capturas (en funcionamiento) de Visual Basic y C#:
Figura 1, la aplicación de Visual Basic
Figura 2: La aplicación de C#
El código completo de Visual Basic:
'------------------------------------------------------------------------------
' Mostrar todos los formularios de una aplicación (ensamblado) (16/Dic/18)
' Estén abiertos o no
' Usando reflection
'
' Este código está basado en el artículo que publiqué el 13/Sep/2004 en:
' http://www.elguille.info/NET/dotnet/reflectionTiposdeunensamblado.htm
'
'
' (c) Guillermo (elGuille) Som, 2018
'------------------------------------------------------------------------------
Option Strict On
Option Infer On
Imports Microsoft.VisualBasic
Imports vb = Microsoft.VisualBasic
Imports System
Imports System.Text
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Diagnostics
Imports System.Linq
Public Class Form1
''' <summary>
''' Para recorrer todos los formularios de un ensamblado
''' estén abiertos o no
''' Basado en el código del elGuille.info:
''' http://www.elguille.info/NET/dotnet/reflectionTiposdeunensamblado.htm
''' </summary>
Private ass As System.Reflection.Assembly
''' <summary>
''' Mostrar todos los formularios de la aplicación actual,
''' estén o no en memoria, usando reflection.
''' Además de los formularios, mostrará:
''' My.Application (solo en VB)
''' Y todos los nombres esmpiezan con el espacio de nombres
''' ESPACIO_DE_NOMBRES.NombreForm
''' </summary>
Private Sub mostrarForms()
' llena una colección con los formularios de esta aplicación
' estén o no en memoria.
' Muestra el resultado en un listbox
lbForms.Items.Clear()
For Each t As Type In ass.GetTypes()
Dim nombreTipo = t.BaseType.Name
' También tendrá My.Application: (solo en VB)
' <espacio de nombres>.My.MyApplication
If nombreTipo.ToLower().Contains("form") Then
lbForms.Items.Add(t.FullName)
End If
Next
End Sub
''' <summary>
''' Muestra el formulario indicado en el argumento,
''' este debe ser con el espacio de nombres completo
'''
''' Si es el actual no lo muestra.
''' Si da error o no es un formulario se avisa.
''' </summary>
Private Sub mostrarFormulario(s As String)
' creamos un tipo a partir del nombre
Dim t As Type = ass.GetType(s)
' instanciamos un nuevo objeto en la memoria
Dim o As Object
' por si hemos seleccionado algo que no es una clase
Try
o = Activator.CreateInstance(t)
Catch ex As Exception
MessageBox.Show(ex.Message, "Mostrar formularios")
Exit Sub
End Try
' si no es un formulario, mostramos un aviso y salimos
If Not (TypeOf o Is Form) Then
MessageBox.Show(s & ", no es un formulario", "Mostrar formularios")
Exit Sub
End If
' convertimos el objeto en un formulario
' como sabemos que si llega aquí es un formulario,
' usamos TryCast que hace menos trabajo que CType o DirectCast.
Dim f As Form = TryCast(o, Form)
If f Is Nothing Then
MessageBox.Show(s & ", parece que no es un formulario",
"Mostrar formularios")
Exit Sub
End If
' si el nombre es el de este formulario,
' lo cerramos y salimos.
If f.Name = Me.Name Then
' no volver a crear este formulario
'f.Close()
Me.BringToFront()
MessageBox.Show(s & " es el formulario de inicio.",
"Mostrar formularios")
Return
End If
' mostramos el formulario.
f.Show()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Mostrar esta ventana en el monitor secundario
MostrarEnVentana2(Me)
' mostrar los formularios de esta aplicación
ass = System.Reflection.Assembly.GetExecutingAssembly()
mostrarForms()
End Sub
Private Sub btnAbrir_Click(sender As Object, e As EventArgs) Handles btnAbrir.Click
' Por si no hay un nombre indicado
If String.IsNullOrWhiteSpace(txtForm.Text) Then Return
' Abrir el formulario indicado en el textbox
mostrarFormulario(txtForm.Text)
End Sub
Private Sub btnSalir_Click(sender As Object, e As EventArgs) Handles btnSalir.Click
Me.Close()
End Sub
Private Sub lbForms_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lbForms.SelectedIndexChanged
txtForm.Text = lbForms.SelectedItem.ToString
End Sub
''' <summary>
''' Mostrar el formulario indicado en la segunda pantalla
''' Código adaptado de la respuesta 42 de:
''' https://stackoverflow.com/questions/2561104/how-do-i-ensure-a-form-displays-on-the-additional-monitor-in-a-dual-monitor-sc
''' </summary>
Public Shared Sub MostrarEnVentana2(frm As Form)
Dim myScreen = Screen.PrimaryScreen
Dim otherScreen = If(Screen.AllScreens.FirstOrDefault(
Function(s) Not s.Equals(myScreen)), myScreen)
' Si queremos indicar dónde mostrarlo
' podemos cambiar los valores de Left y Top
'frm.Left = otherScreen.WorkingArea.Left + 12
'frm.Top = otherScreen.WorkingArea.Top + 12
End Sub
Private Sub btnForm2_Click(sender As Object, e As EventArgs) Handles btnForm2.Click
Dim f As New Form2
f.Show()
End Sub
Private Sub btnForm3_Click(sender As Object, e As EventArgs) Handles btnForm3.Click
Dim f As New Form3
f.Show()
End Sub
End Class
El código completo de C#:
// ----------------------------------------------------------------------------
// Mostrar todos los formularios de una aplicación (ensamblado) (16/Dic/18)
// Estén abiertos o no
// Usando reflection
//
// Este código está basado en el artículo que publiqué el 13/Sep/2004 en:
// http://www.elguille.info/NET/dotnet/reflectionTiposdeunensamblado.htm
//
//
// (c) Guillermo (elGuille) Som, 2018
// ----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace Mostrar_Nombres_Formularios_cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Para recorrer todos los formularios de un ensamblado
/// estén abiertos o no
/// Basado en el código del elGuille.info:
/// http://www.elguille.info/NET/dotnet/reflectionTiposdeunensamblado.htm
/// </summary>
private System.Reflection.Assembly ass;
/// <summary>
/// Mostrar todos los formularios de la aplicación actual,
/// estén o no en memoria, usando reflection.
/// Además de los formularios, mostrará:
/// My.Application (solo en VB)
/// Y todos los nombres esmpiezan con el espacio de nombres
/// ESPACIO_DE_NOMBRES.NombreForm
/// </summary>
private void mostrarForms()
{
// llena una colección con los formularios de esta aplicación
// estén o no en memoria.
// Muestra el resultado en un listbox
lbForms.Items.Clear();
foreach (Type t in ass.GetTypes())
{
var nombreTipo = t.BaseType.Name;
// También tendrá My.Application: (solo en VB)
// <espacio de nombres>.My.MyApplication
if (nombreTipo.ToLower().Contains("form"))
lbForms.Items.Add(t.FullName);
}
}
/// <summary>
/// Muestra el formulario indicado en el argumento,
/// este debe ser con el espacio de nombres completo
///
/// Si es el actual no lo muestra.
/// Si da error o no es un formulario se avisa.
/// </summary>
private void mostrarFormulario(string s)
{
// creamos un tipo a partir del nombre
Type t = ass.GetType(s);
// instanciamos un nuevo objeto en la memoria
object o;
// por si hemos seleccionado algo que no es una clase
try
{
o = Activator.CreateInstance(t);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,
"Mostrar formularios");
return;
}
// si no es un formulario, mostramos un aviso y salimos
if (!(o is Form))
{
MessageBox.Show(s + ", no es un formulario",
"Mostrar formularios");
return;
}
// convertimos el objeto en un formulario
Form f = o as Form;
if (f == null)
{
MessageBox.Show(s + ", parece que no es un formulario",
"Mostrar formularios");
return;
}
// si el nombre es el de este formulario,
// lo cerramos y salimos.
if (f.Name == this.Name)
{
// no volver a crear este formulario
// f.Close()
this.BringToFront();
MessageBox.Show(s + " es el formulario de inicio.",
"Mostrar formularios");
return;
}
// mostramos el formulario.
f.Show();
}
private void Form1_Load(object sender, EventArgs e)
{
// Mostrar esta ventana en el monitor secundario
MostrarEnVentana2(this);
// mostrar los formularios de esta aplicación
ass = System.Reflection.Assembly.GetExecutingAssembly();
mostrarForms();
}
private void btnAbrir_Click(object sender, EventArgs e)
{
//' Por si no hay un nombre indicado
if (String.IsNullOrWhiteSpace(txtForm.Text))
return;
//' Abrir el formulario indicado en el textbox
mostrarFormulario(txtForm.Text);
}
private void btnSalir_Click(object sender, EventArgs e)
{
this.Close();
}
private void lbForms_SelectedIndexChanged(object sender, EventArgs e)
{
txtForm.Text = lbForms.SelectedItem.ToString();
}
/// <summary>
/// Mostrar el formulario indicado en la segunda pantalla
/// Código adaptado de la respuesta 42 de:
/// https://stackoverflow.com/questions/2561104/how-do-i-ensure-a-form-displays-on-the-additional-monitor-in-a-dual-monitor-sc
/// </summary>
public static void MostrarEnVentana2(Form frm)
{
var myScreen = Screen.PrimaryScreen;
var otherScreen = Screen.AllScreens.FirstOrDefault(s => !s.Equals(myScreen))
?? myScreen;
//' Si queremos indicar dónde mostrarlo
//' podemos cambiar los valores de Left y Top
//'frm.Left = otherScreen.WorkingArea.Left + 12
//'frm.Top = otherScreen.WorkingArea.Top + 12
}
}
}
El enlace para descargar el código completo (tanto de Visual Basic como de C#):
Archivo: Mostar_Nombres_Formularios_20181216_2346.zip (204 KB)
MD5 Checksum: DA004D15933BD82355684AC0F20680B1
Nos vemos.
Guillermo