19

在 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。

所以我现在正在调查。

4

4 回答 4

14

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

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

于 2013-05-14T19:00:42.940 回答
8

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

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

我接受了 dlev 的回答,因为它直接引导我找到了答案,即使他对我的确切情况不起作用。

于 2013-05-14T19:36:36.223 回答
6

您需要 WPF 等效的HandleCreated事件,即SourceInitialized. 这应该有效:

public OwnerWindow()
{
    InitializeComponent();

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

请注意,您不必Show使用 OwnerWindow 或 OwnedWindow 即可。

于 2013-05-14T19:43:24.243 回答
6

如果您出于某种原因需要比正常情况更早创建的句柄,或者无法显示窗口,只需添加另一个选项:

new WindowInteropHelper(myWindow).EnsureHandle();

于 2018-04-12T11:27:30.463 回答