Comment puis-je exécuter du code après le chargement d'un formulaire?
Dans. NET, Les formulaires Windows ont un événement qui se déclenche avant le chargement du formulaire (formulaire.Load), mais aucun événement correspondant n'est déclenché après le chargement du formulaire. Je voudrais exécuter une logique après le chargement du formulaire.
Quelqu'un peut-il vous conseiller sur une solution?
7 réponses
Vous pouvez utiliser l'événement "montré": MSDN - Form.Afficher
"l'événement affiché n'est déclenché que la première fois qu'un formulaire est affiché; par la suite, minimiser, maximiser, restaurer, masquer, afficher ou invalider et repeindre ne déclenchera pas cet événement."
, j'utilise parfois (en Charge)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
Ou
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(remplacez "this" par votre variable de formulaire si vous gérez l'événement sur une instance autre que "this").
Cela pousse l'appel sur la boucle Windows-forms, de sorte qu'il est traité lorsque le formulaire traite la file d'attente de messages.
[mise à jour sur demande]
Le Contrôle.Invoquer / Contrôler.Les méthodes BeginInvoke sont destinées à être utilisées avec le threading et constituent un mécanisme permettant de pousser le travail sur le thread de L'interface utilisateur. Normalement, ce est utilisé par les threads de travail etc. Contrôle.Invoquer un appel synchrone, où-comme Contrôle.BeginInvoke effectue un appel asynchrone.
Normalement, ceux-ci seraient utilisés comme:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
Il le fait en poussant un message sur la file d'attente des messages windows; le thread de L'interface utilisateur (à un moment donné) désactive le message, traite le délégué et signale au travailleur qu'il a terminé... jusqu'à présent tout va bien; - p
OK; alors que se passe-t-il si nous utilisons le contrôle.Invoquer / Contrôler.BeginInvoke sur le fil D'interface utilisateur? Il face... si vous appelez le contrôle.Invoke, il est assez judicieux de savoir que le blocage de la file d'attente des messages provoquerait un blocage immédiat - donc si vous êtes déjà sur le thread de L'interface utilisateur, il exécute simplement le code immédiatement... donc ça ne nous aide pas...
Mais Le Contrôle.BeginInvoke fonctionne différemment: iltoujours pousse le travail sur la file d'attente, même si nous sommes déjà sur le thread de L'interface utilisateur. Cela fait une façon vraiment simple de dire "dans un moment", mais sans les inconvénients des minuteries etc (qui encore faudrait faire la même chose de toute façon!).
J'ai eu le même problème, et l'ai résolu comme suit:
En fait, je veux afficher le Message et le fermer automatiquement après 2 secondes. Pour cela, j'ai dû générer (dynamiquement) une forme simple et une étiquette montrant un message, un message d'arrêt pour 1500 ms afin que l'utilisateur le lise. Et fermez la forme créée dynamiquement. L'événement affiché se produit après l'événement de charge. Donc le code est
Form MessageForm = new Form();
MessageForm.Shown += (s, e1) => {
Thread t = new Thread(() => Thread.Sleep(1500));
t.Start();
t.Join();
MessageForm.Close();
};
La première fois qu'il ne démarre pas "AfterLoading",
Il va simplement l'enregistrer pour commencer la prochaine charge.
private void Main_Load(object sender, System.EventArgs e)
{
//Register it to Start in Load
//Starting from the Next time.
this.Activated += AfterLoading;
}
private void AfterLoading(object sender, EventArgs e)
{
this.Activated -= AfterLoading;
//Write your code here.
}
Vous pouvez également essayer de mettre votre code dans l'événement activé du formulaire, si vous voulez qu'il se produise, juste au moment où le formulaire est activé. Vous auriez besoin de mettre une vérification booléenne "a exécuté" si elle n'est censée fonctionner que lors de la première activation.
C'est une vieille question et dépend plus du moment où vous devez commencer vos routines. Puisque personne ne veut une exception de référence nulle, il est toujours préférable de vérifier d'abord null, puis d'utiliser au besoin; cela seul peut vous épargner beaucoup de chagrin.
La raison la plus courante de ce type de question Est lorsqu'un conteneur ou un type de contrôle personnalisé tente d'accéder aux propriétés initialisées en dehors d'une classe personnalisée où ces propriétés n'ont pas encore été initialisées, provoquant ainsi potentiellement des valeurs null pour remplir et peut même provoquer une exception de référence null sur les types d'objets. Cela signifie que votre classe est en cours d'exécution avant d'être complètement initialisée - avant d'avoir fini de définir vos propriétés, etc. Une autre raison possible de ce type de question est quand effectuer des graphiques personnalisés.
Pour répondre au mieux à la question de savoir quand commencer à exécuter du code après l'événement de chargement de formulaire, il faut surveiller le message WM_Paint ou se connecter directement à l'événement paint lui-même. Pourquoi? La peinture événement ne se déclenche lorsque tous les modules sont complètement chargés par rapport à votre événement de chargement de formulaire. Remarque: Cette.visible == true n'est pas toujours vrai quand il est vrai, alors il n'est pas utilisé à cette fin, sauf pour masquer un formulaire.
Ce qui suit est un exemple complet de la façon de commencer à exécuter votre code après l'événement de chargement de formulaire. Il est recommandé de ne pas attacher inutilement la boucle de message paint afin que nous créions un événement qui commencera à exécuter votre code en dehors de cela boucle.
using System.Windows.Forms;
Espace De Noms MyProgramStartingPlaceExample {
/// <summary>
/// Main UI form object
/// </summary>
public class Form1 : Form
{
/// <summary>
/// Main form load event handler
/// </summary>
public Form1()
{
// Initialize ONLY. Setup your controls and form parameters here. Custom controls should wait for "FormReady" before starting up too.
this.Text = "My Program title before form loaded";
// Size need to see text. lol
this.Width = 420;
// Setup the sub or fucntion that will handle your "start up" routine
this.StartUpEvent += StartUPRoutine;
// Optional: Custom control simulation startup sequence:
// Define your class or control in variable. ie. var MyControlClass new CustomControl;
// Setup your parameters only. ie. CustomControl.size = new size(420, 966); Do not validate during initialization wait until "FormReady" is set to avoid possible null values etc.
// Inside your control or class have a property and assign it as bool FormReady - do not validate anything until it is true and you'll be good!
}
/// <summary>
/// The main entry point for the application which sets security permissions when set.
/// </summary>
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
#region "WM_Paint event hooking with StartUpEvent"
//
// Create a delegate for our "StartUpEvent"
public delegate void StartUpHandler();
//
// Create our event handle "StartUpEvent"
public event StartUpHandler StartUpEvent;
//
// Our FormReady will only be set once just he way we intendded
// Since it is a global variable we can poll it else where as well to determine if we should begin code execution !!
bool FormReady;
//
// The WM_Paint message handler: Used mostly to paint nice things to controls and screen
protected override void OnPaint(PaintEventArgs e)
{
// Check if Form is ready for our code ?
if (FormReady == false) // Place a break point here to see the initialized version of the title on the form window
{
// We only want this to occur once for our purpose here.
FormReady = true;
//
// Fire the start up event which then will call our "StartUPRoutine" below.
StartUpEvent();
}
//
// Always call base methods unless overriding the entire fucntion
base.OnPaint(e);
}
#endregion
#region "Your StartUp event Entry point"
//
// Begin executuing your code here to validate properties etc. and to run your program. Enjoy!
// Entry point is just following the very first WM_Paint message - an ideal starting place following form load
void StartUPRoutine()
{
// Replace the initialized text with the following
this.Text = "Your Code has executed after the form's load event";
//
// Anyway this is the momment when the form is fully loaded and ready to go - you can also use these methods for your classes to synchronize excecution using easy modifications yet here is a good starting point.
// Option: Set FormReady to your controls manulaly ie. CustomControl.FormReady = true; or subscribe to the StartUpEvent event inside your class and use that as your entry point for validating and unleashing its code.
//
// Many options: The rest is up to you!
}
#endregion
}
}
Vous pouvez fermer votre formulaire après exécution..
/ / YourForm.ActiveForm.Fermer ();
LoadingForm.ActiveForm.Close();