我有一个用户控件,我在运行时加载到 MainWindow
. 我无法从 UserControl
获取包含窗口的句柄 .
我试过了 this.Parent
,但它总是空的 . 有谁知道如何从WPF中的用户控件获取包含窗口的句柄?
以下是控件的加载方式:
private void XMLLogViewer_MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem application = sender as MenuItem;
string parameter = application.CommandParameter as string;
string controlName = parameter;
if (uxPanel.Children.Count == 0)
{
System.Runtime.Remoting.ObjectHandle instance = Activator.CreateInstance(Assembly.GetExecutingAssembly().FullName, controlName);
UserControl control = instance.Unwrap() as UserControl;
this.LoadControl(control);
}
}
private void LoadControl(UserControl control)
{
if (uxPanel.Children.Count > 0)
{
foreach (UIElement ctrl in uxPanel.Children)
{
if (ctrl.GetType() != control.GetType())
{
this.SetControl(control);
}
}
}
else
{
this.SetControl(control);
}
}
private void SetControl(UserControl control)
{
control.Width = uxPanel.Width;
control.Height = uxPanel.Height;
uxPanel.Children.Add(control);
}
14 回答
尝试使用以下内容
GetWindow方法将为您运行VisualTree并找到托管您控件的窗口 .
您应该在加载控件后运行此代码,以防止GetWindow方法返回null . 例如 . 连线活动:
我会加上我的经验 . 尽管使用Loaded事件可以完成这项工作,但我认为覆盖OnInitialized方法可能更合适 . 首次显示窗口后出现加载 . OnInitialized使您有机会进行任何更改,例如,在窗口呈现之前向窗口添加控件 .
尝试使用VisualTreeHelper.GetParent或使用下面的递归函数来查找父窗口 .
我需要在Loaded事件处理程序中使用Window.GetWindow(this)方法 . 换句话说,我使用Ian Oakes的答案和Alex的答案来获得用户控件的父级 .
这种方法对我有用,但它并不像你的问题那样具体:
这个怎么样:
如果您发现此问题并且VisualTreeHelper不适合您或偶尔工作,您可能需要在算法中包含LogicalTreeHelper .
这是我正在使用的:
我发现UserControl的父级在构造函数中始终为null,但在任何事件处理程序中父级都是正确设置的 . 我想它必须与控件树的加载方式有关 . 因此,为了解决这个问题,您可以在控件Loaded事件中获取父级 .
例如,结帐这个问题WPF User Control's DataContext is Null
其他方式:
它对我有用:
这对我来说不起作用,因为它在树上走得太远,并且获得了整个应用程序的绝对根窗口:
然而,这有助于立即获得窗口:
以上的镀金版(我需要一个通用函数,可以在
MarkupExtension
的上下文中推断Window
: -MyWrapper.Owner()
将在以下基础上正确推断窗口:根
Window
通过走可视树(如果在UserControl
的上下文中使用)使用它的窗口(如果它在
Window
标记的上下文中使用)