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'上调用构造函数 指定的绑定约束引发了异常。
实际上,我查看了内部异常,并说:
无法将Owner属性设置为尚未显示的Window 先前。
所以我现在正在调查。
答案 0 :(得分:12)
问题在于,因为WPF仅在第一次显示WPF窗口时创建本机窗口,所以您不能将尚未显示的窗口设置为Owner
(因为它会建立本机窗口) “owner - >拥有”关系,但原生句柄尚不存在。)
您可以在所有者窗口中处理StateChanged
事件,确保“显示”新状态,然后在该点设置拥有窗口的Owner
。或者,您可以在此时创建并显示拥有的窗口。
答案 1 :(得分:5)
我最终订阅了Window.Activated
,而不是Window.StateChanged
。请务必按照评论中的建议在处理程序中取消订阅。
private void OnActivated(object sender, EventArgs eventArgs)
{
owned.Owner = this;
Activated -= OnActivated;
}
我接受了dlev的回答,因为它直接导致我找到答案,即使他的确不适合我的确切情况。
答案 2 :(得分:5)
您需要相当于HandleCreated
事件的WPF,即SourceInitialized
。这应该有效:
public OwnerWindow()
{
InitializeComponent();
SourceInitialized += (s, a) =>
{
var owned = new OwnedWindow();
owned.Owner = this;
};
}
请注意,您不必使用Show
OwnerWindow或OwnedWindow来实现此目的。
答案 3 :(得分:1)
如果由于某种原因需要先于正常创建的句柄,或者无法显示窗口,只需添加另一个选项:
new WindowInteropHelper(myWindow).EnsureHandle();