c# - form - splash screen visual studio 2017
Splash Screen esperando hasta que termine el hilo (5)
Todavía tengo un problema con la pantalla de presentación. No quiero usar la propiedad SC.TopMost=true
.
Ahora mi escenario de aplicación es el siguiente:
en progeram.cs:
[STAThread]
static void Main()
{
new SplashScreen(_tempAL);// where _tempAL is an arrayList
Application.Run(new Form1(_tempAL));
}
en la clase SplashScreen:
public SplashScreen(ArrayList _Data)
{
DisplaySplash()
}
private void DisplaySplash()
{
this.Show();
this.TopMost = true;
this.CenterToScreen();
this.SetTopLevel(true);
_allServerNarrators = new string[10];
for (int i = 0; i < _allServerNarrators.Length; i++)
_allServerNarrators[i] = null;
GetFromServer();
this.Hide();
_serverData = new ArrayList();
_thisData.Add(_allServerNarrators);
_thisData.Add(_serverNarrators);
}
private void GetFromServer()
{
_serverNarrators = new ArrayList();
string _file = "Suras.serverNar";
if (!Directory.Exists("c://ASGAQuraan"))
Directory.CreateDirectory("c://ASGAQuraan");
while (counter < 4 && _serverFiles == null)
{
if (Download("c://ASGAQuraan", _ftpServerIP, _file))
{
StreamReader _strReader = new StreamReader
("c://ASGAQuraan//"+_file,System.Text.Encoding.Default);
string _line = _strReader.ReadLine();
string _word;
while (true)
{
while (_line != null)
{
_word = _line.Substring(0, _line.IndexOf("*"));
int _narId = Convert.ToInt32(_word);
_line = _line.Substring(2);
int k = 0;
_serverNarratorNode = new ArrayList();
while (true)
{
int ind = _line.IndexOf("*");
if (ind > 0 && ind < _line.Length)
{
string str = _line.Substring(0, (ind));
if (k == 0)
{
_allServerNarrators[_narId] = str;
_serverNarratorNode.Add(str);
}
else
{
_serverNarratorNode.Add(str);
}
_line = _line.Substring(ind + 1);
k++;
}
else
{
_line = null;
break;
}
}
_serverNarrators.Add(_serverNarratorNode);
_serverFiles = "added";
}
_line = _strReader.ReadLine();
if (_line == null)
{
break;
}
}
}
else
counter++;
}
}
Lo que quiero es algo en la clase de pantalla de bienvenida que espere hasta que finalice el hilo.
Para obtener más detalles, dígame qué debo decirle.
Ha ingresado en un territorio peligroso al crear la interfaz de usuario antes de llamar a Application.Run (). Application.Run es esencialmente la bomba de mensajes de su programa. Al mostrar la interfaz de usuario antes de iniciar la bomba de mensajes de la aplicación, la interacción UI típica es imposible en la interfaz de usuario prematura. Para una pantalla de bienvenida, esto puede no parecer relevante, pero importará si (por ejemplo) hay una solicitud para hacer que la pantalla de inicio desaparezca si se hace clic en ella, o si desea usar un Trabajador de fondo.
Esto puede solucionarse creando una bomba de mensajes en su pantalla emergente (haciéndola modal mediante una llamada a ShowDialog () en lugar de Mostrar ()), pero eso es tratar el síntoma cuando tratar el problema realmente no es tan difícil.
Recomiendo encarecidamente la respuesta de Nobugz en este caso. El marco proporciona la asistencia que necesita. Mientras que las características en el espacio de nombres Microsoft.VisualBasic no siempre son muy reconocibles para los programadores de C #, pueden ser un verdadero ahorro de tiempo y salvavidas para casos como este.
¡Buena suerte!
La misma pregunta, la misma respuesta:
.NET Framework tiene una excelente compatibilidad integrada para pantallas de presentación. Inicie un nuevo proyecto WF, Proyecto + Agregar referencia, seleccione Microsoft.VisualBasic. Agregue un nuevo formulario, llámelo frmSplash. Abra Project.cs y haga que se vea así:
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;
namespace WindowsFormsApplication1 {
static class Program {
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new MyApp().Run(args);
}
}
class MyApp : WindowsFormsApplicationBase {
protected override void OnCreateSplashScreen() {
this.SplashScreen = new frmSplash();
}
protected override void OnCreateMainForm() {
// Do your time consuming stuff here...
//...
System.Threading.Thread.Sleep(3000);
// Then create the main form, the splash screen will close automatically
this.MainForm = new Form1();
}
}
}
Lamentablemente, aún no tengo la reputación suficiente para comentar la respuesta de alguien. :( Esta es la respuesta al comentario del coronel Panics sobre la respuesta de Hans Passants .
Su problema fue que un MessageBox
muestra desde el new FormMain(args)
se mostrará detrás de la pantalla de new FormMain(args)
. La clave es invocar el MessageBox desde el hilo en el que se ejecuta la pantalla de bienvenida:
splashScreen.Invoke(new Action(() => {
MessageBox.Show(splashScreen, "the message");
}));
Donde splashScreen
es una referencia al objeto de la pantalla de bienvenida que se ha creado en OnCreateSplashScreen
y obviamente tiene que splashScreen
al nuevo objeto Form1
.
Realmente deberías dar más detalles sobre tu problema. Podría estar completamente equivocado, pero voy a tomar una foto en la oscuridad. Por lo que estoy imaginando que está sucediendo y quieres, quieres que se muestre la pantalla de inicio, hacer un procesamiento en otro hilo y luego la pantalla de bienvenida para irse cuando haya terminado.
Para hacer esto, querrá mover la llamada GetFromServer()
a un BackgroundWorker
. Luego mueve el
this.Hide();
_serverData = new ArrayList();
_thisData.Add(_allServerNarrators);
_thisData.Add(_serverNarrators);
código al controlador de eventos BackgroundWorker_RunWorkerCompleted
.
Para usar BackgroundWorker
:
1) Inicializar el BackGroundWorker
BackgroundWorker myWorker = new BackgroundWorker();
2) Agregar controladores de eventos
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
//put the work you want done in this one
myWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
//this gets fired when the work is finished
3) Agregue código a los manejadores de eventos.
4) Llame a myWorker.RunWorkerAsync()
para comenzar a trabajar.
Como nota aparte, no parece que esté haciendo nada con ArrayList
que está pasando al constructor de la pantalla de bienvenida. ¿Esto es intencionado?
Seguir dos hilos es un poco confuso, pero voy a tomar una puñalada y decir esto ...
No entiendo completamente su diseño aquí, pero si el problema es que cuando lanza una segunda aplicación, la pantalla de presentación se pone blanca ... Lo más probable es que se deba a que la pantalla de bienvenida está ocupada ejecutando todo ese código en GetFromServer. (). Tan ocupado que no tiene tiempo para volver a pintarse a sí mismo.
Para solucionar este problema, le sugiero que utilice el componente BackGroundWorker para ejecutar el método GetFromServer. Esto ejecutará ese método en un hilo separado y dejará libre el hilo del formulario para volver a pintarse.