У меня есть пользовательский элемент управления, который я загружаю во время 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);
}
Я добавлю свой опыт. Хотя использование события Loaded может сделать эту работу, я думаю, что может быть более подходящим переопределить метод OnInitialized. Загружается происходит после первого отображения окна. OnInitialized дает вам возможность вносить любые изменения, например, добавлять элементы управления в окно до его визуализации.
источник
Window.GetWindow
по- прежнему возвращаетсяnull
вOnInitialized
. Кажется, работает только вLoaded
случае.Попробуйте использовать VisualTreeHelper.GetParent или использовать рекурсивную функцию ниже, чтобы найти родительское окно.
источник
Мне нужно было использовать метод Window.GetWindow (this) в обработчике событий Loaded. Другими словами, я использовал ответ Иана Оукса в сочетании с ответом Алекса, чтобы получить родительский элемент управления пользователя.
источник
Этот подход работал для меня, но он не так конкретен, как ваш вопрос:
источник
Если вы нашли этот вопрос, и VisualTreeHelper не работает для вас или работает спорадически, вам может потребоваться включить LogicalTreeHelper в ваш алгоритм.
Вот что я использую:
источник
LogicalTreeHelper.GetParent
в коде.Как насчет этого:
источник
Я обнаружил, что родительский элемент UserControl всегда равен нулю в конструкторе, но в любых обработчиках событий родительский элемент установлен правильно. Я думаю, это как-то связано с тем, как загружается дерево управления. Таким образом, чтобы обойти это, вы можете просто получить родителя в элементе управления Loaded.
В качестве примера проверки этого вопроса DataContext элемента управления пользователя WPF имеет значение Null
источник
По-другому:
источник
Это работает для меня:
источник
Это не сработало для меня, так как зашло слишком далеко вверх по дереву и получило абсолютное корневое окно для всего приложения:
Тем не менее, это сработало, чтобы получить немедленное окно:
источник
источник
источник
Позолоченное издание выше (мне нужна общая функция, которая может выводить
Window
в контекстеMarkupExtension
: -MyWrapper.Owner()
будет правильно выводить окно на следующей основе:Window
путем обхода визуального дерева (если используется в контекстеUserControl
)Window
разметки)источник
Разные подходы и разные стратегии. В моем случае я не смог найти окно моего диалога ни с помощью VisualTreeHelper, ни с помощью методов расширения от Telerik, чтобы найти родителя данного типа. Вместо этого я нашел свое диалоговое окно, которое принимает пользовательское внедрение содержимого с использованием Application.Current.Windows.
источник
Window.GetWindow(userControl)
Возвращает фактическое окно только после того, как окно было инициализировано (InitializeComponent()
метод закончен).Это означает, что если ваш пользовательский элемент управления инициализируется вместе с его окном (например, вы помещаете свой пользовательский элемент управления в файл xaml окна), то при
OnInitialized
событии пользовательского элемента управления вы не получите окно (оно будет нулевым), потому что в в этом случае пользовательский элемент управленияOnInitialized
событие срабатывает до инициализации окна.Это также означает, что если ваш пользовательский элемент управления инициализируется после его окна, то вы можете получить окно уже в конструкторе пользовательского элемента управления.
источник
Если вы просто хотите получить определенный родительский элемент, а не только окно, определенный родительский элемент в древовидной структуре, а также не использовать счетчики рекурсии или жесткого цикла прерывания, вы можете использовать следующее:
Только не помещайте этот вызов в конструктор (так как
Parent
свойство еще не инициализировано). Добавьте его в обработчик событий загрузки или в другие части вашего приложения.источник