Jos*_*eph 16 c# wpf window .net-4.0
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
...
}
Run Code Online (Sandbox Code Playgroud)
我应该澄清一下,删除它owned.Owner = this;也会删除运行时错误.
例外的细节:
XamlParseException未处理
在类型'... MainView'上调用与指定绑定约束匹配的构造函数引发了异常.
实际上,我查看了内部异常,它说:
无法将Owner属性设置为之前未显示的Window.
所以我现在正在调查.
dle*_*lev 12
问题是,因为WPF仅在第一次显示WPF窗口时创建本机窗口,所以您不能将尚未显示的窗口设置为Owner(因为它建立了本机窗口"所有者 - >拥有"关系,但原生句柄尚不存在.)
您可以StateChanged在所有者窗口上处理事件,确保"显示"新状态,然后Owner在该点设置拥有的窗口.或者,您可以在该点创建并显示拥有的窗口.
我最终订阅了Window.Activated,而不是Window.StateChanged.请务必按照评论中的建议在处理程序中取消订阅.
private void OnActivated(object sender, EventArgs eventArgs)
{
owned.Owner = this;
Activated -= OnActivated;
}
Run Code Online (Sandbox Code Playgroud)
我接受了dlev的答案,因为它让我直接找到答案,即使他的确不适合我的确切情况.
您需要WPF HandleCreated事件的等效项,即SourceInitialized。这应该工作:
public OwnerWindow()
{
InitializeComponent();
SourceInitialized += (s, a) =>
{
var owned = new OwnedWindow();
owned.Owner = this;
};
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不必Show使用OwnerWindow或OwnedWindow即可运行。
如果出于某种原因需要比正常情况更早创建句柄,或者无法显示窗口,只需添加另一个选项:
new WindowInteropHelper(myWindow).EnsureHandle();