WPF définit ses propres Main()
méthode. Comment dois-je procéder pour la remplacer par ma propre méthode ? Main
qui ouvre (normalement) la fenêtre WPF MainWindow
(par exemple, pour ajouter un mode de script non WPF via des arguments de ligne de commande) ?
Réponses
Trop de publicités?Quelques exemples illustrent la modification de l'action de construction d'App.xaml, qui passe de ApplicationDefinition
a Page
et de rédiger votre propre Main()
qui instancie le App
et appelle sa classe Run()
mais cela peut avoir des conséquences indésirables sur la résolution des ressources de l'application dans App.xaml.
Je vous suggère plutôt de faire votre propre Main()
dans sa propre classe et en attribuant l'objet de démarrage à cette classe dans les propriétés du projet :
public class EntryPoint {
[STAThread]
public static void Main(string[] args) {
if (args != null && args.Length > 0) {
// ...
} else {
var app = new App();
app.InitializeComponent();
app.Run();
}
}
}
Je le fais pour tirer parti de certaines AppDomain
les événements auxquels il faut s'abonner avant qu'autre chose ne se produise (comme les AssemblyResolve
). Les conséquences indésirables du réglage de App.xaml sur Page
que j'ai vécues comprenaient mon UserControl
Les vues (M-V-VM) ne résolvent pas les ressources détenues dans App.xaml pendant la conception.
En général, j'édite App.xaml
pour ajouter ce support :
<Application x:Class="SomeNamespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
La partie pertinente étant que j'ai changé de StartupUri
a Startup
avec un gestionnaire d'événement dans App.xaml.cs
. Voici un exemple :
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
int verbose = 0;
var optionSet = new OptionSet
{
{ "v|verbose", "verbose output, repeat for more verbosity.",
arg => verbose++ }
};
var extra = optionSet.Parse(e.Args);
var mainWindow = new MainWindow(verbose);
mainWindow.Show();
}
}
Les gars Le problème est que votre programme a deux méthodes statiques Main(), ce qui va amener le compilateur à se plaindre entre ; Pour résoudre ce problème, essayez l'une des choses suivantes :
- Indiquez au compilateur que votre méthode statique Main() doit être le point d'entrée de l'exécution - Définissez le paramètre "Startup object" de votre projet sur la classe contenant votre méthode statique Main() (cliquez avec le bouton droit de la souris sur le projet dans l'explorateur de solutions, choisissez "Propriétés", puis recherchez le paramètre "Startup object" sous l'onglet "Application").
- Désactiver la génération automatique de la méthode statique Main() d'App.g.cs - Dans l'explorateur de solutions, faire un clic droit sur App.xaml, choisir "Propriétés", puis changer l'"Action de construction" de "ApplicationDefinition" à "Page".
Créez une nouvelle classe avec votre méthode statique Main personnalisée. À la fin de cette méthode, il suffit d'appeler l'App.Main() original généré par WPF :
public class Program
{
[STAThread]
public static void Main(string[] args)
{
// Your initialization code
App.Main();
}
}
Définissez ensuite le paramètre "Startup object" de votre projet sur la classe contenant votre statique Main().
En utilisant une Main() personnalisée, vous pouvez rencontrer des problèmes parce que StartupUri n'est pas défini.
Vous pouvez l'utiliser pour le définir sans maux de tête dans votre classe App (n'oubliez pas de supprimer StartupUri dans App.xaml et de définir son Build Action à Page) :
[STAThread]
static void Main()
{
App app = new App();
app.InitializeComponent();
app.Run();
}
protected void OnStartup(object sender, StartupEventArgs e)
{
var toUri = new UriTypeConverter();
StartupUri = (Uri)toUri.ConvertFrom("MainWindow.xaml");
...
}