Родительский контроль пользователя WPF - PullRequest
176 голосов
/ 19 ноября 2008

У меня есть пользовательский элемент управления, который я загружаю в 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 ]

3 голосов
/ 06 июня 2013

Другой способ:

var main = App.Current.MainWindow as MainWindow;
1 голос
/ 23 августа 2012
DependencyObject GetTopParent(DependencyObject current)
{
    while (VisualTreeHelper.GetParent(current) != null)
    {
        current = VisualTreeHelper.GetParent(current);
    }
    return current;
}

DependencyObject parent = GetTopParent(thisUserControl);
1 голос
/ 18 мая 2011
DependencyObject parent = ExVisualTreeHelper.FindVisualParent<UserControl>(this);
0 голосов
/ 02 июня 2016

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

public sealed class MyExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider) =>
        new MyWrapper(ResolveRootObject(serviceProvider));
    object ResolveRootObject(IServiceProvider serviceProvider) => 
         GetService<IRootObjectProvider>(serviceProvider).RootObject;
}

class MyWrapper
{
    object _rootObject;

    Window OwnerWindow() => WindowFromRootObject(_rootObject);

    static Window WindowFromRootObject(object root) =>
        (root as Window) ?? VisualParent<Window>((DependencyObject)root);
    static T VisualParent<T>(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<T>(VisualTreeHelper.GetParent(node));
    }
}

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

  • корень Window путем обхода визуального дерева (если используется в контексте UserControl)
  • окно, в котором оно используется (если оно используется в контексте разметки Window)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...