13 votes

wPF VisualTreeHelper.GetParent renvoie une classe erronée ?

J'ai défini le XAML suivant.

<Popup x:Class="EMS.Controls.Dictionary.MapTip"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    PopupAnimation="Slide"
     AllowsTransparency="True" Placement="Mouse"       
       x:Name="root"                   
      >

    <Popup.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../Resources/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Popup.Resources>
    <Viewbox x:Name="viewBox" IsHitTestVisible="True">
        <Grid Background="Transparent" Name="mainGrid">

        </Grid>
    </Viewbox>
</Popup>

Si je remonte l'arbre visuel en utilisant VisualTreeHelper.GetParent à partir de "mainGrid", je finis par obtenir System.Windows.Controls.Primitives.PopupRoot, mais jamais la fenêtre contextuelle elle-même. Quelqu'un a-t-il une théorie sur la raison de ce phénomène et sur ce que je peux faire pour y remédier ? J'ai besoin de Popup et non de PopupRoot.

TIA.

18voto

Jmix90 Points 1830

Le contenu d'une popup est ajouté à un arbre visuel différent avec un parent qui est le PopupRoot mais vous pouvez utiliser l'aide d'arbre logique pour obtenir la popup avec ce snippet :

LogicalTreeHelper.GetParent()

De MSDN :

Lorsque vous ajoutez du contenu à un contrôle Popup, le contrôle Popup devient le parent logique du contenu. De même, le contenu du Popup est considéré comme l'enfant logique du Popup. Le contenu enfant n'est pas ajouté à l'arbre visuel qui contient le contrôle Popup. Au lieu de cela, le contenu enfant est rendu dans une fenêtre distincte qui possède sa propre arborescence visuelle lorsque la propriété IsOpen est définie sur true.

++

5voto

rudigrobler Points 8883

Essayez de parcourir l'arbre logique et non l'arbre visuel.

LogicalTreeHelper.GetParent()

5voto

Neeraj Points 59

LogicalTreeHelper n'est pas en mesure d'atteindre la fenêtre contextuelle, le mieux que l'on puisse faire est d'essayer d'utiliser le nom "PopupRoot" pour le comparer à celui de la fenêtre contextuelle. GetType().Name .

4voto

Pavel Korsukov Points 885

Utilisez ça :

Popup oPopup = VisualHelper.GetLogicalParent<Popup>(oThumb);

...

public static T GetLogicalParent<T>(DependencyObject p_oElement)
    where T : DependencyObject
{
    DependencyObject oParent = p_oElement;
    Type oTargetType = typeof(T);
    do
    {
        oParent = LogicalTreeHelper.GetParent(oParent);
    }
    while (
        !(
            oParent == null
            || oParent.GetType() == oTargetType
            || oParent.GetType().IsSubclassOf(oTargetType)
        )
    );

    return oParent as T;
}

1voto

Sachin Rana Points 11
    private void btnRemove_Click(object sender, RoutedEventArgs e)
    {

        CloseScatterViewItem((SurfaceButton)sender);
    }

    private void CloseScatterViewItem(SurfaceButton button)
    {
        DependencyObject parent = button;
        while ((parent as ScatterViewItem) == null)
        {

            // Get the next parent.
            parent = LogicalTreeHelper.GetParent(parent) != null ? LogicalTreeHelper.GetParent(parent) : VisualTreeHelper.GetParent(parent);
            ScatterViewItem item = parent as ScatterViewItem;
            if (item != null)
            {
                DependencyObject scatterView = item;
                while ((scatterView as ScatterView) == null)
                {
                    scatterView = LogicalTreeHelper.GetParent(scatterView) != null ? LogicalTreeHelper.GetParent(scatterView) : VisualTreeHelper.GetParent(scatterView);
                    ScatterView FoundSV = scatterView as ScatterView;
                    if (FoundSV != null)
                    {
                        //FoundSV.Items.Remove(item);
                        FadeOutAndRemove(FoundSV, item);
                        return;
                    }
                }
            }
        }

    }
    public static void FadeOutAndRemove(ScatterView sv, ScatterViewItem svi)
    {
        try
        {
            svi.Opacity = 1.0;

            var a = new DoubleAnimation
            {
                From = 1.0,
                To = 0.0,
                FillBehavior = FillBehavior.Stop,
                BeginTime = TimeSpan.FromSeconds(0),
                Duration = new Duration(TimeSpan.FromSeconds(0.5))
            };

            var storyboard = new Storyboard();
            storyboard.Children.Add(a);

            Storyboard.SetTarget(a, svi);
            Storyboard.SetTargetProperty(a, new PropertyPath(UIElement.OpacityProperty));

            storyboard.Completed += delegate
            {
                svi.Visibility = Visibility.Hidden;
                sv.Items.Remove(svi);
                svi.Content = null;
                svi = null;
            };

            storyboard.Begin();
        }
        catch (Exception ex)
        {
            //Handle error

        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X