我希望WPF应用程序仅在某些条件下启动。我尝试了以下但没有成功:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (ConditionIsMet) // pseudo-code
{
base.OnStartup(e);
}
}
}
但是,即使条件不满足,应用也能正常运行
答案 0 :(得分:13)
试试这个:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
if (MyCondition)
{
ShowSomeDialog("Hey, I Can't start because...");
this.Shutdown();
}
}
答案 1 :(得分:3)
另一种解决方案
设计
<Application x:Class="SingleInstanceWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
</Application>
背后的代码
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
if (ConditionIsMet)
{
var window = new MainWindow();
window.Show();
}
else
{
this.Shutdown();
}
}
}
答案 2 :(得分:0)
这可能是我真的非常努力的方式,但我发现通过假设任何事情与启动时的调用优先级/顺序作斗争是徒劳的。我真的希望在应用程序启动期间引发的任何异常立即冒泡到最外层的异常处理程序,但即使引发了一个异常处理程序,我的MVVM Locator对象也会自动实例化,因为它被定义为应用程序级资源。
这意味着鸡蛋在鸡蛋之前到达,但在同一个鸡蛋已经破碎之后!
所以解决方案是:
1)从App.xaml中删除MVVM定位器。
2)创建Application_Startup事件
在顶部添加以下行:
#region Handlers For Unhandled Exceptions
// anything else to do on startup can go here and will fire after the base startup event of the application
// First make sure anything after this is handled
// Creates an instance of the class holding delegate methods that will handle unhandled exceptions.
CustomExceptionHandler eh = new CustomExceptionHandler();
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(eh.OnAppDomainException);
// this ensures that any unhandled exceptions bubble up to a messagebox at least
Dispatcher.CurrentDispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(eh.OnDispatcherUnhandledException);
#endregion Handlers For Unhandled Exceptions
3)将App Start绑定到App.xaml中的Application_Startup事件 e.g。
Startup="Application_Startup" <<<< this name is arbitrary but conventional AFAICT
4)在Applicaton_Startup中,创建如下的ViewModelLocator:
Resources.Add("Locator", new ViewModelLocator());
//You can use FindResource and an exception will be thrown straightaway as I recall
if (!(TryFindResource("Locator") == null))
throw new ResourceReferenceKeyNotFoundException("ViewModelLocator could not be created", "Locator");
5)然后,在找到资源后立即打开MainWindow,但只有在Locator成功实例化的情况下才会打开
Uri uri = new Uri("pack:Views/MainWindow.xaml", UriKind.RelativeOrAbsolute);
Application.Current.StartupUri = uri;
如果定位器上的构造函数失败,那么步骤(4)将立即抛出异常,并且可以重新开始。
然后,步骤4中的异常处理如下(此示例使用RadMessageBox但可以随意修复:
public void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
try
{
var result = this.ShowExceptionDialog(e.Exception);
}
catch
{
RadMessageBox.Show("Fatal Dispatcher Error - the application will now halt.", Properties.Resources.CaptionSysErrMsgDlg,
MessageBoxButton.OK, MessageBoxImage.Stop, true);
}
finally
{
e.Handled = true;
// TERMINATE WITH AN ERROR CODE -1!
//Environment.Exit(-1);
}
}