在Parent的构造函数中设置窗口所有者的麻烦

WPF中是否有任何错误,将窗口的Owner属性设置为该父窗口构造函数中的父窗口? 不应该,对吗? 那么为什么我从以下代码中获取XamlParseException

 public partial class MainView : Window { private readonly OwnedWindow owned; public MainView() { InitializeComponent(); owned = new OwnedWindow(); owned.DataContext = DataContext; var window = GetWindow(this); owned.Owner = this; //Setting to window causes the same error ... } 

我应该澄清一下,删除owned.Owner = this; 还会删除运行时错误。

例外的细节:

XamlParseException未处理

在类型’… MainView’上调用与指定绑定约束匹配的构造函数引发了exception。

实际上 ,我查看了内部exception,它说:

无法将Owner属性设置为之前未显示的Window。

所以我现在正在调查。

问题是,因为WPF仅在第一次显示WPF窗口时创建本机窗口,所以您不能将尚未显示的窗口设置为Owner (因为它建立了本机窗口“所有者 – >拥有”关系,但原生句柄尚不存在。)

您可以在所有者窗口上处理StateChanged事件,确保“显示”新状态,然后在该点设置拥有窗口的Owner 。 或者,您可以在该点创建并显示拥有的窗口。

我最终订阅了Window.Activated ,而不是Window.StateChanged 。 请务必按照评论中的建议在处理程序中取消订阅。

  private void OnActivated(object sender, EventArgs eventArgs) { owned.Owner = this; Activated -= OnActivated; } 

我接受了dlev的答案,因为它让我直接找到答案,即使他的确不适合我的确切情况。

你需要WPF等效的HandleCreated事件,它是SourceInitialized 。 这应该工作:

 public OwnerWindow() { InitializeComponent(); SourceInitialized += (s, a) => { var owned = new OwnedWindow(); owned.Owner = this; }; } 

请注意,您无需Show OwnerWindow或OwnedWindow即可。

如果由于某种原因需要先于正常创建的句柄,或者无法显示窗口,只需添加另一个选项:

new WindowInteropHelper(myWindow).EnsureHandle();