Пользовательский контроль WPF Parent

У меня есть пользовательский элемент управления, который я загружаю в MainWindow во время выполнения. Я не могу получить дескриптор windows содержания из UserControl .

Я попробовал this.Parent , но он всегда null. Кто-нибудь знает, как получить дескриптор содержащего windows из пользовательского элемента управления в 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); } 

Попробуйте использовать следующие

 Window parentWindow = Window.GetWindow(userControlRefernce); 

Метод GetWindow будет обрабатывать VisualTree для вас и находить окно, в котором находится ваш контроль.

Вы должны запустить этот код после загрузки элемента управления, чтобы предотвратить возврат метода GetWindow. EG подключить событие:

 this.Loaded += new RoutedEventHandler(UserControl_Loaded); 

Я добавлю свой опыт. Хотя использование события Loaded может выполнять эту работу, я думаю, что это может быть более подходящим для переопределения метода OnInitialized. Загружается после появления windows. 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); } } 

Мне нужно было использовать метод Window.GetWindow (this) в обработчике Loaded event. Другими словами, я использовал ответ Яна Оукса в сочетании с ответом Алекса, чтобы получить родительский элемент управления пользователя.

 public MainView() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainView_Loaded); } void MainView_Loaded(object sender, RoutedEventArgs e) { Window parentWindow = Window.GetWindow(this); ... } 

Этот подход работал для меня, но это не так специфично, как ваш вопрос:

 App.Current.MainWindow 

Как насчет этого:

 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)); } } } 

Я обнаружил, что родительский элемент UserControl всегда имеет значение null в конструкторе, но в любом случае обработчики родительского элемента установлены правильно. Я предполагаю, что это должно иметь какое-то отношение к тому, как загружается дерево управления. Чтобы обойти это, вы можете просто получить родительский элемент в элементе Loaded.

Для примера проверьте этот вопрос DataContext WPF User Control – Null

Если вы находите этот вопрос, и 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); } 

Другой путь:

 var main = App.Current.MainWindow as MainWindow; 

Он работает для меня:

 DependencyObject GetTopLevelControl(DependencyObject control) { DependencyObject tmp = control; DependencyObject parent = null; while((tmp = VisualTreeHelper.GetParent(tmp)) != null) { parent = tmp; } return parent; } 

Это не сработало для меня, поскольку оно зашло слишком далеко по дереву и получило абсолютное корневое окно для всего приложения:

 Window parentWindow = Window.GetWindow(userControlReference); 

Однако это сработало, чтобы получить ближайшее окно:

 DependencyObject parent = uiElement; int avoidInfiniteLoop = 0; while ((parent is Window)==false) { parent = VisualTreeHelper.GetParent(parent); avoidInfiniteLoop++; if (avoidInfiniteLoop == 1000) { // Something is wrong - we could not find the parent window. break; } } Window window = parent as Window; window.DragMove(); 
 DependencyObject parent = ExVisualTreeHelper.FindVisualParent(this); 
 DependencyObject GetTopParent(DependencyObject current) { while (VisualTreeHelper.GetParent(current) != null) { current = VisualTreeHelper.GetParent(current); } return current; } DependencyObject parent = GetTopParent(thisUserControl); 

Позолоченная версия выше (мне нужна общая функция, которая может вывести Window в контексте MarkupExtension : –

 public sealed class MyExtension : MarkupExtension { public override object ProvideValue(IServiceProvider serviceProvider) => new MyWrapper(ResolveRootObject(serviceProvider)); object ResolveRootObject(IServiceProvider serviceProvider) => GetService(serviceProvider).RootObject; } class MyWrapper { object _rootObject; Window OwnerWindow() => WindowFromRootObject(_rootObject); static Window WindowFromRootObject(object root) => (root as Window) ?? VisualParent((DependencyObject)root); static T VisualParent(DependencyObject node) where T : class { if (node == null) throw new InvalidOperationException("Could not locate a parent " + typeof(T).Name); var target = node as T; if (target != null) return target; return VisualParent(VisualTreeHelper.GetParent(node)); } } 

MyWrapper.Owner() правильно выведет Окно на следующем основании:

  • корневое Window , пройдя визуальное дерево (если оно используется в контексте UserControl )
  • окно, в котором оно используется (если оно используется в контексте разметки Window )
  • Отключить ключ ускорителя ярлыков WPF (текст подчеркивания отсутствует)
  • Как установить событие MouseOver / триггер для границы в XAML?
  • WPF XAML Bindings и CurrentCulture Display
  • Каковы различные режимы привязки WPF?
  • Как отформатировать число десятичных знаков в wpf с помощью стиля / шаблона?
  • Как я могу создать поле со списком WPF шириной самого широкого элемента в XAML?
  • быстрое преобразование Bitmap в BitmapSource wpf
  • Обнаружить, если в C # нажата какая-либо клавиша (не A, B, а любая)
  • {x: Null} против прозрачного?
  • Установите надстрочный индекс и индекс в форматированном тексте в wpf
  • Шифрование учетных данных в приложении WPF
  • Interesting Posts

    Как отключить комбинацию клавиш Option-Space для неразрывных пробелов?

    Отчеты Jasper – выравнивание динамических текстовых полей и их меток горизонтально

    Выделение селектора jQuery

    Удаление строк из одного файла, находящегося в другом файле

    Как автоматически обрезать примерно однородный фон из серии изображений?

    Передача переменной количества аргументов вокруг

    Файл SharedPreferences

    Получение местоположения элемента управления, относящегося ко всему экрану?

    .htaccess & WordPress: Исключить папку из RewriteRule

    Windows Store не запускается

    Thinkpad X30 посередине

    Виртуальная виртуальная машина импортирована VM – VERR_NOT_SUPPORTED – VERR_CFGM_VALUE_NOT_FOUND

    Как разработать алгоритм для расчета голограммы

    Как я могу определить, как пользователь нажимает клавишу HOME в моей деятельности?

    JAX-WS = Когда Apache CXF установлен, он «крадет» стандартную реализацию JDK JAX-WS по умолчанию, как ее решить?

    Давайте будем гением компьютера.