我有以下代码行。
Application.Current.MainWindow = new MainWindow();
将构造函数放在调试器告诉我的行上,Application.Current.MainWindow为null。 然后构造函数抛出异常。在catch块中,Application.Current.MainWindow不再为null。不应修改Application.Current.MainWindow的值,但它是。
如果我改为:
Window w = new MainWindow();
在按预期抛出异常后,w为null。
我错过了什么?
更新
只调用Window子类的构造函数会导致Application.Current.MainWindow更改为指向该实例。即使构造函数抛出异常,也会发生这种情况。这使应用程序处于不一致状态。
例如,它将让我调用Application.Current.MainWindow.Show,它会创建各种问题,因为该窗口的状态无效。
答案 0 :(得分:1)
查看Application.MainWindow
属性的来源
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以指示“这是我的主窗口”。 建议编程风格在代码而不是Windows [0]中引用MainWindow。
运行时无法在构造函数完成之前设置对已分配内存的引用。它可以作为优化来完成,但只能使用特定于框架的类,例如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
,所以这会在您抛出异常之前发生。