我有一个用户控件,我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); }
Ian Oakes.. 341
尝试使用以下内容
Window parentWindow = Window.GetWindow(userControlReference);
GetWindow方法将为您移动VisualTree并找到托管您控件的窗口.
您应该在加载控件后运行此代码,以防止GetWindow方法返回null.EG发布一个事件:
this.Loaded += new RoutedEventHandler(UserControl_Loaded);
我发现它返回null的原因.我将此代码放入我的用户控件的构造函数中.您应该在加载控件后运行此代码.EG连接一个事件:this.Loaded + = new RoutedEventHandler(UserControl_Loaded); (105认同)
仍然返回null.这就像控件没有父级一样. (6认同)
我使用上面的代码并获取parentWindow也为我返回null. (2认同)
小智.. 33
我会加上我的经验.虽然使用Loaded事件可以完成这项工作,但我认为覆盖OnInitialized方法可能更合适.首次显示窗口后出现加载.OnInitialized使您有机会进行任何更改,例如,在窗口呈现之前向窗口添加控件.
尝试使用以下内容
Window parentWindow = Window.GetWindow(userControlReference);
GetWindow方法将为您移动VisualTree并找到托管您控件的窗口.
您应该在加载控件后运行此代码,以防止GetWindow方法返回null.EG发布一个事件:
this.Loaded += new RoutedEventHandler(UserControl_Loaded);
我会加上我的经验.虽然使用Loaded事件可以完成这项工作,但我认为覆盖OnInitialized方法可能更合适.首次显示窗口后出现加载.OnInitialized使您有机会进行任何更改,例如,在窗口呈现之前向窗口添加控件.
尝试使用VisualTreeHelper.GetParent或使用下面的递归函数来查找父窗口.
public static Window FindParentWindow(DependencyObject child) { DependencyObject parent= VisualTreeHelper.GetParent(child); //CHeck if this is the end of the tree if (parent == null) return null; Window parentWindow = parent as Window; if (parentWindow != null) { return parentWindow; } else { //use recursion until it reaches a Window return FindParentWindow(parent); } }
我需要在Loaded事件处理程序中使用Window.GetWindow(this)方法.换句话说,我使用Ian Oakes的答案和Alex的答案来获得用户控件的父级.
public MainView() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainView_Loaded); } void MainView_Loaded(object sender, RoutedEventArgs e) { Window parentWindow = Window.GetWindow(this); ... }
这个怎么样:
DependencyObject parent = ExVisualTreeHelper.FindVisualParent(this); public static class ExVisualTreeHelper { /// /// Finds the visual parent. /// ////// The sender. /// public static T FindVisualParent (DependencyObject sender) where T : DependencyObject { if (sender == null) { return (null); } else if (VisualTreeHelper.GetParent(sender) is T) { return (VisualTreeHelper.GetParent(sender) as T); } else { DependencyObject parent = VisualTreeHelper.GetParent(sender); return (FindVisualParent (parent)); } } }
这种方法对我有用,但它不像你的问题那样具体:
App.Current.MainWindow
如果您发现此问题并且VisualTreeHelper不适合您或偶尔工作,您可能需要在算法中包含LogicalTreeHelper.
这是我正在使用的:
public static T TryFindParent(DependencyObject current) where T : class { DependencyObject parent = VisualTreeHelper.GetParent(current); if( parent == null ) parent = LogicalTreeHelper.GetParent(current); if( parent == null ) return null; if( parent is T ) return parent as T; else return TryFindParent (parent); }
我发现UserControl的父级在构造函数中始终为null,但在任何事件处理程序中父级都是正确设置的.我想它必须与控件树的加载方式有关.因此,为了解决这个问题,您可以在控件Loaded事件中获取父级.
对于示例结帐,此问题WPF用户控件的DataContext为空