Замена точки входа WPF

WPF определяет свой собственный метод Main(). Как мне заменить его собственным методом Main, который (обычно) открывает WPF MainWindow (например, чтобы добавить сценарий без WPF с помощью аргументов командной строки)?

Ответ 1

В некоторых примерах показано изменение действия сборки App.xaml от ApplicationDefinition до Page и запись собственного Main(), который создает экземпляр класса App и вызывает его метод Run(), но это может привести к некоторым нежелательным последствиям в разрешение ресурсов приложения в App.xaml.

Вместо этого я предлагаю создать собственный Main() в своем собственном классе и установить объект запуска для этого класса в свойствах проекта:

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();
        }
    }
}

Я делаю это, чтобы воспользоваться некоторыми событиями AppDomain, которые должны быть подписаны, прежде чем что-либо еще произойдет (например, AssemblyResolve). Нежелательные последствия установки App.xaml на Page, которые я испытал, включали мои UserControl Views (M-V-VM), не разрешающие ресурсы, хранящиеся в App.xaml во время разработки.

Ответ 2

Обычно я редактирую App.xaml, чтобы добавить эту поддержку:

<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">

Соответствующая часть меня изменила с StartupUri на Startup с обработчиком события в App.xaml.cs. Вот пример:

/// <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();
    }
}

Ответ 3

ребята Проблема в том, что ваша программа имеет два статических метода Main(), которые заставят компилятор жаловаться между ними; Чтобы решить эту проблему, выполните одно из следующих действий:

  • Сообщите компилятору, что ваш статический метод Main() должен быть точкой ввода выполнения. Задайте параметры проекта "Объект запуска" для класса, содержащего ваш статический метод Main() (щелкните правой кнопкой мыши по проекту в обозревателе решений, выберите "Свойства", затем найдите параметр "Объект запуска" на вкладке "Приложение" ).
  • Отключите автогенерирование метода static main() в App.g.css. В обозревателе решений щелкните правой кнопкой мыши на App.xaml, выберите "Свойства", затем измените "Действие сборки" с "ApplicationDefinition" на "Страница".

Ответ 4

Создайте новый класс с помощью собственного статического метода Main. В конце этого метода просто вызовите исходный файл App.Main(), сгенерированный WPF:

public class Program
{
    [STAThread]
    public static void Main(string[] args)
    {
        // Your initialization code
        App.Main();
    }
}

Затем установите для ваших проектов "Объект запуска" класс, содержащий ваш статический Main().

Ответ 5

Используя пользовательский Main(), вы можете столкнуться с проблемами, поскольку StartupUri не установлен.

Вы можете использовать это, чтобы установить его без головных болей в своем классе App (не забудьте удалить StartupUri из App.xaml и установить его действие сборки на страницу):

[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");
...
}