c# - tutoriel - wpf xaml




Contrôle utilisateur WPF parent (10)

Autrement:

var main = App.Current.MainWindow as MainWindow;

J'ai un contrôle utilisateur que je charge dans une MainWindow à l'exécution. Je ne peux pas obtenir un handle sur la fenêtre contenant à partir du UserControl .

J'ai essayé this.Parent , mais c'est toujours nul. Est-ce que quelqu'un sait comment obtenir un handle de la fenêtre contenant à partir d'un contrôle utilisateur dans WPF?

Voici comment le contrôle est chargé:

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

Cela fonctionne pour moi:

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

Cette approche a fonctionné pour moi mais ce n'est pas aussi spécifique que votre question:

App.Current.MainWindow

Essayez d'utiliser VisualTreeHelper.GetParent ou utilisez la fonction récursive suivante pour rechercher la fenêtre parente.

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

J'ai trouvé que le parent d'un UserControl est toujours null dans le constructeur, mais dans tous les gestionnaires d'événements, le parent est correctement défini. Je suppose que cela doit avoir quelque chose à voir avec la façon dont l'arbre de contrôle est chargé. Donc, pour contourner cela, vous pouvez simplement obtenir le parent dans l'événement Controls Loaded.

Pour un exemple de commande, cette question DataContext de contrôle utilisateur WPF est Null


J'avais besoin d'utiliser la méthode Window.GetWindow (this) dans le gestionnaire d'événements Loaded. En d'autres termes, j'ai utilisé la réponse de Ian Oakes en combinaison avec la réponse d'Alex pour obtenir le parent d'un contrôle utilisateur.

public MainView()
{
    InitializeComponent();

    this.Loaded += new RoutedEventHandler(MainView_Loaded);
}

void MainView_Loaded(object sender, RoutedEventArgs e)
{
    Window parentWindow = Window.GetWindow(this);

    ...
}

Que dis-tu de ça:

DependencyObject parent = ExVisualTreeHelper.FindVisualParent<UserControl>(this);

public static class ExVisualTreeHelper
{
    /// <summary>
    /// Finds the visual parent.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender">The sender.</param>
    /// <returns></returns>
    public static T FindVisualParent<T>(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<T>(parent));
        }
    } 
}

Si vous trouvez cette question et que VisualTreeHelper ne fonctionne pas pour vous ou ne fonctionne pas sporadiquement, vous devrez peut-être inclure LogicalTreeHelper dans votre algorithme.

Voici ce que j'utilise:

public static T TryFindParent<T>(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<T>(parent);
}

DependencyObject GetTopParent(DependencyObject current)
{
    while (VisualTreeHelper.GetParent(current) != null)
    {
        current = VisualTreeHelper.GetParent(current);
    }
    return current;
}

DependencyObject parent = GetTopParent(thisUserControl);

DependencyObject parent = ExVisualTreeHelper.FindVisualParent<UserControl>(this);




wpf