查看Application.MainWindow 属性的来源
来源:http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Application.cs,cf9c51e402f97b05
public Window MainWindow
{
get
{
VerifyAccess();
return _mainWindow;
}
set
{
VerifyAccess();
//
// Throw if an attempt is made to change RBW.
// or we are browser hosted, main window is null, and attempt is made to change RBW.
//
if ( ( _mainWindow is RootBrowserWindow )
||
((BrowserCallbackServices != null ) &&
( _mainWindow == null ) &&
( !( value is RootBrowserWindow ))) )
{
throw new InvalidOperationException( SR.Get( SRID.CannotChangeMainWindowInBrowser ) ) ;
}
if (value != _mainWindow)
{
_mainWindow = value;
}
}
}
这是一个值得关注的问题。另一点是其他线程或框架本身可以将其设置在其他地方。检查此评论
默认情况下 - MainWindow 将设置为应用程序中打开的第一个窗口。
但是,可以通过编程方式设置 MainWindow 以指示“这是我的主窗口”。
推荐的编程风格是在代码中引用 MainWindow 而不是 Windows[0]。
在构造函数完成之前,运行时无法设置对分配内存的引用。它可能是作为一种优化完成的,但仅限于特定于框架的类,例如System.String。
编辑:查看Window.Initialize 方法
private void Initialize()
{
// AVTempUIPermission avtUIPermission = new AVTempUIPermission(AVTUIPermissionNewWindow.LaunchNewWindows);
// CASRemoval:avtUIPermission.Demand();
// this makes MeasureCore / ArrangeCore to defer to direct MeasureOverride and ArrangeOverride calls
// without reading Width / Height properties and modifying input constraint size parameter...
BypassLayoutPolicies = true;
// check if within an app && on the same thread
if (IsInsideApp == true)
{
if (Application.Current.Dispatcher.Thread == Dispatcher.CurrentDispatcher.Thread)
{
// add to window collection
// use internal version since we want to update the underlying collection
App.WindowsInternal.Add(this);
if (App.MainWindow == null)
{
App.MainWindow = this;
}
}
else
{
App.NonAppWindowsInternal.Add(this);
}
}
}
特别是在行:
App.WindowsInternal.Add(this);
if (App.MainWindow == null)
{
App.MainWindow = this;
}
这是设置Window 属性的地方。因为你的MainWindow 是从Window 派生的,所以这发生在你抛出异常之前。