wPF VisualTreeHelper.GetParent возвращает неправильный класс? - PullRequest
13 голосов
/ 25 сентября 2010

У меня определен следующий XAML.

<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>

Если я подхожу к визуальному дереву с помощью VisualTreeHelper.GetParent из "mainGrid", я в конечном итоге получаю System.Windows.Controls.Primitives.PopupRoot, но никогдаполучить само всплывающее окно.Кто-нибудь с теорией, почему это и что я могу с этим поделать?Мне нужен Popup, а не PopupRoot.

TIA.

Ответы [ 6 ]

17 голосов
/ 26 сентября 2010

Содержимое во всплывающем окне добавляется в другое визуальное дерево с родителем, который является PopupRoot, но вы можете использовать помощник логического дерева, чтобы получить всплывающее окно с этим фрагментом:

LogicalTreeHelper.GetParent()

Из MSDN:

Когда вы добавляете контент в элемент управления Popup, элемент управления Popup становится логическим родителем для содержимого.Точно так же контент Popup считается логическим потомком Popup.Дочернее содержимое не добавляется в визуальное дерево, содержащее элемент управления Popup.Вместо этого дочерний контент отображается в отдельном окне, которое имеет свое собственное визуальное дерево, когда для свойства IsOpen установлено значение true.

++

4 голосов
/ 22 июля 2011

LogicalTreeHelper не может дозвониться до всплывающего окна, и лучшее, что можно сделать, это попробовать использовать имя «PopupRoot» для сравнения с GetType().Name.

4 голосов
/ 25 сентября 2010

Попробуйте пройти логическое дерево, а не визуальное дерево

LogicalTreeHelper.GetParent()
3 голосов
/ 01 ноября 2011

Используйте это:

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;
}
2 голосов
/ 28 сентября 2016

Основываясь на этом ответе и ответах, представленных здесь (и благодаря комментарию Wouter), я наконец-то пришел к следующему:

using System.Windows.Media;
using System.Windows.Media.Media3D;

public static class FamilyHelper
{
    public static T FindAncestor<T>(this DependencyObject dObj) where T : DependencyObject
    {
        while (true)
        {
            if (dObj == null) return null;

            var parent = VisualTreeHelper.GetParent(dObj as Visual ?? new UIElement())
                         ?? VisualTreeHelper.GetParent(dObj as Visual3D ?? new UIElement())
                         ?? LogicalTreeHelper.GetParent(dObj);

            if (parent is T) return (T) parentT;
            dObj = parent;
        }
    }
}

, который никогда не ошибается и работаетдля всех типов органов управления, например

var element = sender as UIElement;
var parentWindow = element.FindAncestor<Window>();
1 голос
/ 12 июля 2013
    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

        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...