在Parent's构造函数中设置Window's所有者时遇到问题
本文关键字:所有者 问题 Window 遇到 构造函数 Parent 设置 | 更新日期: 2023-09-27 18:13:38
在WPF中设置窗口的所有者属性到父窗体的构造函数中是否有任何错误?不应该有,对吧?那么为什么我从下面的代码得到一个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 was unhandled
类型为"…"的构造函数的调用MainView'匹配指定的绑定约束抛出异常。
实际上,我看了看内部异常,它说:
不能将Owner属性设置为未显示的窗口以前。
我正在调查这个
问题是,因为WPF只在第一次显示WPF窗口时创建本机窗口,所以您不能将尚未显示的窗口设置为Owner
(因为这建立了本机窗口"owner -> owned"的关系,但本机句柄还不存在)
您可以在所有者窗口上处理StateChanged
事件,确保新状态"显示",然后在该点设置所有者窗口的Owner
。或者,您可以创建并显示所拥有的窗口。
我最终订阅了Window.Activated
,而不是Window.StateChanged
。请务必在处理程序中取消订阅,正如评论中建议的那样。
private void OnActivated(object sender, EventArgs eventArgs)
{
owned.Owner = this;
Activated -= OnActivated;
}
我接受了dlev的答案,因为它直接引导我找到了答案,尽管他的答案并不适合我的实际情况。
如果您出于某种原因需要比正常情况更早创建句柄,或者无法显示窗口,则添加另一个选项:
new WindowInteropHelper(myWindow).EnsureHandle();
您需要与HandleCreated
事件等价的WPF事件,即SourceInitialized
。这应该可以工作:
public OwnerWindow()
{
InitializeComponent();
SourceInitialized += (s, a) =>
{
var owned = new OwnedWindow();
owned.Owner = this;
};
}
请注意,您不必Show
OwnerWindow或OwnedWindow为这个工作。