加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么VisualTreeHelper.GetChildrenCount()为Popup返回0

发布时间:2020-12-16 00:05:05 所属栏目:百科 来源:网络整理
导读:我将重点放在Popup的开头: wcl:FocusHelper.IsFocused="{Binding RelativeSource={RelativeSource Self},Path=IsOpen}" FocusHelper类代码: public static class FocusHelper{ public static readonly DependencyProperty IsFocusedProperty = DependencyP
我将重点放在Popup的开头:

wcl:FocusHelper.IsFocused="{Binding RelativeSource={RelativeSource Self},Path=IsOpen}"

FocusHelper类代码:

public static class FocusHelper
{
     public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.RegisterAttached("IsFocused",typeof(bool?),typeof(FocusHelper),new FrameworkPropertyMetadata(IsFocusedChanged));

        public static bool? GetIsFocused(DependencyObject element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (bool?)element.GetValue(IsFocusedProperty);
        }

        public static void SetIsFocused(DependencyObject element,bool? value)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            element.SetValue(IsFocusedProperty,value);
        }

        private static void IsFocusedChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
        {
            var fe = (FrameworkElement)d;

            if (e.OldValue == null)
            {
                fe.GotFocus += ElementGotFocus;
                fe.LostFocus += ElementLostFocus;
                fe.IsVisibleChanged += ElementIsVisibleChanged;
            }

            if (e.NewValue == null)
            {
                fe.GotFocus -= ElementGotFocus;
                fe.LostFocus -= ElementLostFocus;
                fe.IsVisibleChanged -= ElementIsVisibleChanged;
                return;
            }

            if ((bool)e.NewValue)
            {
                fe.SetFocusWithin();
            }
        }

        private static void ElementIsVisibleChanged(object sender,DependencyPropertyChangedEventArgs e)
        {
            var fe = (FrameworkElement)sender;

            if (fe.IsVisible 
                && (bool)(((FrameworkElement) sender).GetValue(IsFocusedProperty))) // Bring focus to just become visible element.
                fe.Focus();
        }

        private static void ElementGotFocus(object sender,RoutedEventArgs e)
        {
            ((FrameworkElement)sender).SetCurrentValue(IsFocusedProperty,true);
        }

        private static void ElementLostFocus(object sender,false);
        }

        /// <summary>
        /// Tries to set focus to the element or any other element inside this one.
        /// Tab index is respected
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static bool SetFocusWithin(this DependencyObject element)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            var inputElement = element as IInputElement;
            if (inputElement == null || !inputElement.Focus())
            {
                var children = element.GetVisualChildrenSortedByTabIndex().Where(child => !(child is Control) || (bool)child.GetValue(Control.IsTabStopProperty) );
                return children.Any(SetFocusWithin);
            }

            return true;
        }
    }

ElementTreeHelper类部分:

public static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject parent)
        {
            if (parent == null)
                throw new ArgumentNullException("parent");

            var count = VisualTreeHelper.GetChildrenCount(parent);
            for (var i = 0; i < count; i++)
                yield return VisualTreeHelper.GetChild(parent,i);
        }

        public static IEnumerable<DependencyObject> GetVisualChildrenSortedByTabIndex(this DependencyObject parent)
        {
            if (parent == null)
                throw new ArgumentNullException("parent");

            return parent.GetVisualChildren().OrderBy(KeyboardNavigation.GetTabIndex);
        }

问题是
当父是Popup时,var count = VisualTreeHelper.GetChildrenCount(parent)== 0.

UPDATE

答案是here

解决方法

Popup本身并不托管Child.相反,它创建一个PopupRoot(内部类),它是创建的新HWND的根视觉,用于在单独的顶级窗口(或xbap中的子窗口)中托管弹出窗口的内容. Popup的子项托管在该PopupRoot中的AdornerDecorator中.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读