【问题标题】:VisualElements not shown on first load of page首次加载页面时未显示 VisualElements
【发布时间】:2014-09-07 15:24:49
【问题描述】:



我正在尝试在页面加载后更新我的所有文本框元素。

问题

为什么第一次加载时没有返回文本框?

说明

我有一个带有 Frame 元素的 MainWindow,用于在 wpf 页面之间导航。
因此,当用户单击菜单项时,页面会加载到框架中。
这是用户单击 MenuItem 时的代码:

将新页面加载到框架中的代码(方法导航)

    public static void Navigate(Page page, double fadeTime = 0.6)
    {
        MainWindow MainWin = (MainWindow) Application.Current.MainWindow;
        Frame NavFrame = MainWin.mainFrame;


        if (NavFrame.Content != page)
        {
            NavFrame.NavigationService.Navigate(page);

            //Gebruik Dispatcher om Fadein Effect te kunnen toepassen
            Frame mainFrame = NavFrame;
            NavFrame.Dispatcher.BeginInvoke(
                new Action(() =>
                {
                    //Voeg Animatie Toe
                    NavFrame.Opacity = 0;
                    DoubleAnimation fadeIn = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(fadeTime), FillBehavior.HoldEnd);
                    mainFrame.BeginAnimation(UIElement.OpacityProperty, fadeIn, HandoffBehavior.Compose);
                }));                

            //Bij navigeren naar andere pagina roep GC aan.
            GC.Collect();
        }

        int amount = 0;
        //Apply Color on CaretBrush
        foreach (TextBox tb in Worker.FindVisualChildren<TextBox>(page))
        {
            amount++;
            tb.CaretBrush = (Brush)new BrushConverter().ConvertFromString("#FF8E9CFF");
        }

        Worker.ShowModernBox(amount.ToString()); //Custom messagebox
        page.UpdateDefaultStyle();
        page.UpdateLayout();
    }

FindVisualChildren 方法

 //Haal alle elementen van huidige view op.
    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        //Indien het object gevuld is met componenten
        if (depObj != null)
        {
            //Voor ieder Object in huidige view
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                //geef Child terug
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T) child;
                }

                //geef CHilds van CHild terug.
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

问题

用户第一次加载此页面时,它将 int 数量返回为 0,当第二次单击时,我将返回所有 19 个文本框。这是为什么?当我调试它并展开我的页面时,我可以看到那里的文本框

【问题讨论】:

  • 第一次导航到页面时,根本没有创建可视化树。但是,为什么要采用如此复杂的方法?您可以改为将所有 TextBox 的 CaretBrush 属性绑定到单个视图模型属性或静态资源或其他任何内容,您可以在页面导航到时更改这些属性。
  • Navigate() 是异步的,所以你应该注册到LoadCompleted
  • Pragmateek,谢谢!对 LoadCompleted 无效,但对 Frame 上的 ContentRendered 有效。

标签: c# .net wpf visualtreehelper


【解决方案1】:

感谢 Pragmateek。
解决方案:将以下代码绑定到 ContentRendered 事件

 foreach (TextBox tb in Worker.FindVisualChildren<TextBox>(page))
    {
        amount++;
        tb.CaretBrush = (Brush)new BrushConverter().ConvertFromString("#FF8E9CFF");
    }

    Worker.ShowModernBox(amount.ToString()); //Custom messagebox
    page.UpdateDefaultStyle();
    page.UpdateLayout();

原因

在 visualTree 查找元素时,根本没有渲染内容。因此,通过将其绑定到 ContentRendered 事件,等待页面首先呈现其所有内容。

学分归 Pragmateek

【讨论】:

    猜你喜欢
    • 2018-09-02
    • 2013-05-11
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多