Passing command line arguments into WPF C# applica

2019-05-23 03:53发布

问题:

This question already has an answer here:

  • WPF Command Line Arguments, a smart way? 2 answers

So from this post I got the following code for passing command line arguments into my WPF Application

public partial class App : Application
{
    private string _customerCode;
    public string CustomerCode
    {
        get { return _customerCode; }
        set { _customerCode = value; }
    }


    protected override void OnStartup(StartupEventArgs e)
    {
        if (e.Args.Count() != 0)
        {
            CustomerCode = e.Args[0].Replace("/", string.Empty); 
        }
    }
}

The application then starts my MainWindow.xaml and the application runs but in the viewModel for MainWindow.xaml (MainViewModel.cs) I would like to access the value of App.CustomerCode.

Is this the right way to deal with command line arguments and is it possible to access the value of CustomerCode?

回答1:

I do not know your real intent, but the code below should help you.

You can try this by adding some arguments on project debug settings.

If your parameters contains blank spaces you should use "" signs to distinguish them. But instead of doing this you can use Application Config file for some cases. You can add some Settings from Project Settings or directly editing by settings.settings file.

If you need/fancy startup args, here is it.

//App
public partial class App : Application
{
    public string CustomerCode { get; set; }
    protected override void OnStartup(StartupEventArgs e)
    {

        this.CustomerCode=e.Args[0].ToString();
        base.OnStartup(e);
    }
}


//MainWindow
 public partial class MainWindow : Window
{
    public MainWindow()
    {
        var hereIsMyCode=(Application.Current as App).CustomerCode;
        InitializeComponent();
    }
}


回答2:

One of the easy ways to access the customer code is to overwrite the Application.Current property with the new keyword (as more or less Davut has pointed out in his answer):

public class App : Application
{
    public static new App Current
    {
        get { return (App) Application.Current; }
    }

    public string CustomerCode { get; set; }
    protected override void OnStartup(StartupEventArgs e)
    {
        this.CustomerCode = e.Args[0].Replace("/", string.Empty);
        base.OnStartup(e);
    }
}

In your view model you can then access the customer code by writing App.Current.CustomerCode.

However, if you want a more object-oriented way regarding the SOLID principles, I would advise to do the following: in your OnStartup method, create the view model and the main window in code and show it. Using this approach, you can inject the customer code to the view model, e.g. via constructor injection. The OnStartup method would look like this:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // Composition root
    var customerCode = e.Args[0].Replace("/", string.Empty);

    // Here I inject the customer code to the view model so that 
    // it can save it in a field and use it later.
    // This is called dependency injection (here it's constructor injection)
    var mainWindowViewModel = new MainWindowViewModel(customerCode);
    MainWindow = new MainWindow { DataContext = mainWindowViewModel };
    MainWindow.Show();
}

For this to work, you have to remove the StartupUri entry in App.xaml - otherwise your manually created main window will not show up.

Your view model would look like this:

public class MainWindowViewModel
{
    private readonly string _customerCode;

    public MainWindowViewModel(string customerCode)
    {
        if (customerCode == null)
            throw new ArgumentNullException("customerCode");

        _customerCode = customerCode;
    }

    // Other code in this class can access the _customerCode field
    // to retrieve the value from the command line
}

This approach is a more flexible than to access the static App.Current property as your view model is independent of the App class (i.e. it has no references to it).

If you want to learn more about dependency injection, just google it, you'll find plenty of example. I can also recommend the excellent book Dependency Injection in .NET by Mark Seemann, if you want to dive in more.