【问题标题】:WPF - choose startup window based on some conditionWPF - 根据某些条件选择启动窗口
【发布时间】:2012-04-23 06:57:26
【问题描述】:

点击Run或按Ctrl + F5运行我的程序时,是否可以根据某些检查条件打开不同的窗口?

即,如果满足某些条件,我希望打开一个特定的窗口,但如果不满足,我想打开另一个窗口。

应该就像在打开任何窗口之前应该首先检查条件一样

if(File.Exists(<path-to-file>)
    Open Window 1
else
    Open Window 2

这可能吗?

【问题讨论】:

  • 这里急需更多细节,关于“一些条件”、“新窗口”、“另一个窗口”等。
  • 对不起,alex.. 我刚刚添加了一个更容易理解的部分
  • @alex 我认为他的意思是他有两个窗口。当他启动程序时,它应该根据某些条件选择这些窗口之一。 sai sindhu:对吗?

标签: c# .net wpf wpf-controls


【解决方案1】:

查看 App.xaml

删除StartupUri="MainWindow.xaml"

添加Startup="Application_Startup"新事件处理程序

<Application x:Class="YourProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="Application_Startup">

App.xaml.cs 后面的表单代码创建 Application_Startup like...

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        //add some bootstrap or startup logic 
        var identity = AuthService.Login();
        if (identity == null)
        {
            LoginWindow login = new LoginWindow();
            login.Show();
        }
        else
        {
            MainWindow mainView = new MainWindow();
            mainView.Show();
        }
    }

【讨论】:

  • 别忘了包含using System.Windows;
  • 有趣的是,在实例化窗口时应该非常小心。我有一个登录对话框,必须在 MainWindow 之前打开,所以我这样做了,在 LoginDialog 关闭后,应用程序终止。我通过先实例化 MainWindow 而不实际显示它来修复它,然后 登录对话框关闭后,运行它。
  • 我只想提一下你需要添加“window.Closed += (o, eventArgs) => Shutdown();”或者您的应用程序不会终止并且会逗留。除非您将 ShutdownMode 配置为最后一个窗口。
  • 访问 AuthService.Login() 的最佳方式是什么;假设我有 Unity DI 设置。我需要检查数据库中是否有活动登录。 _identityService.GetLastLogin() 如何获取 _identityService 的实例
【解决方案2】:

您可以使用 App.xaml 来启动您的应用程序,并且正如 Nikhil Agrawal 所说,动态更改 StartupUri

但是,您仍然可以从 public static void Main() 启动您的应用程序。只需删除App.xaml中的StartupUri="MainWindow.xaml"属性,将Program类添加到包含Main方法的项目中,然后进入项目属性并将启动对象设置为YourAssemblyName.Program

[STAThread]
public static void Main(string[] args)
{
    var app = new Application();
    var mainWindow = new MainWindow();
    app.Run(mainWindow);
}

注意,STAThreadAttribute 是必需的。如果您需要自己的 Application 派生版本,例如 WPF 项目如何默认创建派生 App 类,您可以在 Main 中使用它来代替 Application。但是,如果您不需要它,您可以直接使用基类 Application 并从您的项目中删除派生类。

【讨论】:

    【解决方案3】:

    App.xaml 中,我们有一个Application 标记具有StartupUri 属性。我认为你应该在 App.xaml.cs 部分编写这段代码

    public App()
    {
          // Your Code
    }
    

    并将StartUpUri 设置为所需的 xaml 文件。

    【讨论】:

    • 记得调用基础构造函数来保持正常行为,所以:public App() : base() { ... },否则App不会加载你的窗口。
    【解决方案4】:

    我知道这是一个很老的问题。但是我遇到了类似的问题,最近我在 WPF .NET Core 3.1 中使用依赖注入,感觉有人会遇到类似的挑战,所以发布这个答案

    这是我的启动,您可以在其中设置条件启动窗口

    protected override async void OnStartup(StartupEventArgs e)
            {
                await host.StartAsync();
                var userService = host.Services.GetService<IUserRepository>();
                var lastActiveUser = userService.LastActive();
                if (lastActiveUser != null)
                {
                    DefaultWindow = host.Services.GetRequiredService<MainWindow>();
                    DefaultWindow.Show();
                }
                else
                {
                    DefaultWindow = host.Services.GetRequiredService<LoginWindow>();
                    DefaultWindow.Show();
                }
                base.OnStartup(e);
            }
    

    用于初始化主机的应用构造函数

    public App()
            {
                host = Host.CreateDefaultBuilder()  // Use default settings
                                                    //new HostBuilder()          // Initialize an empty HostBuilder
                       .ConfigureAppConfiguration((context, builder) =>
                       {
                           builder.SetBasePath(Directory.GetCurrentDirectory())
                           // Add other configuration files...
                           .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                           Configuration = builder.Build();
    
                       }).ConfigureServices((context, services) =>
                       {
                           ConfigureServices(context.Configuration, services);
                       })
                       .ConfigureLogging(logging =>
                       {
                           // Add other loggers...
                           logging.ClearProviders();
                           logging.AddConsole();
                       }).Build();
            }
    

    依赖注入

    private void ConfigureServices(IConfiguration configuration,
            IServiceCollection services)
            {
                _services = services;
                _services.Configure<AppSettings>(Configuration
                    .GetSection(nameof(AppSettings)));
    
                _services.AddDbContext<SmartDbContext>(options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("SqlConnection"));
                });
    
                _services.AddScoped<IUserRepository, UserRepository>();
                _services.AddScoped<ILoginDataContext, LoginDataContext>();
                _services.AddTransient(typeof(MainWindow));
                _services.AddTransient(typeof(LoginWindow));
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      • 2017-12-12
      • 2021-08-18
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      相关资源
      最近更新 更多