将命令行参数传递到WPF C#应用程序并访问其值

时间:2014-09-04 08:42:28

标签: c# wpf command-line-arguments

所以从this post我得到了以下代码,用于将命令行参数传递到我的WPF应用程序

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

然后应用程序启动我的MainWindow.xaml并运行应用程序,但是在ViewModel for MainWindow.xaml(MainViewModel.cs)中我想访问App.CustomerCode的值。

这是处理命令行参数的正确方法吗?是否可以访问CustomerCode的值?

2 个答案:

答案 0 :(得分:4)

访问客户代码的一种简单方法是使用Application.Current关键字覆盖new属性(正如Davut在答案中指出的那样):

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

在您的视图模型中,您可以通过编写App.Current.CustomerCode来访问客户代码。

但是,如果您想要更加面向对象的SOLID原则,我建议您执行以下操作:在OnStartup方法中,在代码中创建视图模型和主窗口并显示它。使用此方法,您可以将客户代码注入视图模型,例如通过构造函数注入。 OnStartup方法如下所示:

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

为此,您必须删除StartupUri 中的App.xaml条目 - 否则您的手动创建的主窗口将不会显示。

您的视图模型如下所示:

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
}

这种方法比访问静态App.Current属性更灵活,因为您的视图模型独立于App类(即它没有引用它)。

如果您想了解有关依赖注入的更多信息,只需谷歌搜索,您就会找到很多例子。如果你想深入了解,我还可以推荐Mark Seemann的优秀书Dependency Injection in .NET

答案 1 :(得分:3)

我不知道你的真实意图,但下面的代码可以帮助你。

您可以通过在项目调试设置中添加一些参数来尝试此操作。

如果参数包含空格,则应使用""标志来区分他们。但是,在某些情况下,您可以使用Application Config文件而不是这样做。您可以从“项目设置”添加一些“设置”,也可以通过settings.settings文件直接进行编辑。

如果你需要/花哨的启动args,就在这里。

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