问题 可以举个例子,说明什么时候应该使用UIElement.UpdateLayout()?


我正在读这个 UpdateLayout()方法 在MSDN中。

它说:

确保此元素的所有可视子元素都正确   更新了布局。

但我不明白是什么意思 布局未正确更新

我已经使用Silverlight / WPF超过一年了,但我还没有使用过这种方法一次。

那么有人可以给我一个需要使用这种方法的例子吗?所以我真的能理解它的作用以及何时使用它?


11440
2018-03-28 13:36


起源



答案:


如果您需要一个控件来立即完成其布局,您可能想要调用它,以便您可以基于此做一些事情。例如,你可以打电话 UpdateLayout 在一个儿童控制,使它得到一个 ActualHeight 和 ActualWidth,如果你想根据它做其他事情(例如,定位它,或绘制具有相应大小的东西)。


9
2018-03-29 08:14



哦,哇,正如你所说它实际上有效!我试图动态创建一个Grid和一个Button。按钮 ActualHeight/ActualWidth只有 0.00 我添加到网格后,但一旦我执行 UpdateLayout 它给了我实际的价值!现在我看到了我能用到的东西,谢谢! +1 - King Chan
+1正是我所看到的;调用UpdateLayout()后,ActualWidth变为可用。 - Sabuncu
我今天遇到的另一个场景。在 OnDropDownOpened 对于我需要调用的自定义组合框 ItemContainerGenerator.ContainerFromItem,但它在第一次调用时返回null,并且仅在后续工作中正常工作 OnDropDownOpened 调用。我必须在调用之前添加UpdateLayout() ContainerFromItem,然后它也开始工作第一次电话。我知道替代解决方案是关闭虚拟化使用 VirtualizingStackPanel 但出于性能原因,我不想这样做。 - JustAMartin


答案:


如果您需要一个控件来立即完成其布局,您可能想要调用它,以便您可以基于此做一些事情。例如,你可以打电话 UpdateLayout 在一个儿童控制,使它得到一个 ActualHeight 和 ActualWidth,如果你想根据它做其他事情(例如,定位它,或绘制具有相应大小的东西)。


9
2018-03-29 08:14



哦,哇,正如你所说它实际上有效!我试图动态创建一个Grid和一个Button。按钮 ActualHeight/ActualWidth只有 0.00 我添加到网格后,但一旦我执行 UpdateLayout 它给了我实际的价值!现在我看到了我能用到的东西,谢谢! +1 - King Chan
+1正是我所看到的;调用UpdateLayout()后,ActualWidth变为可用。 - Sabuncu
我今天遇到的另一个场景。在 OnDropDownOpened 对于我需要调用的自定义组合框 ItemContainerGenerator.ContainerFromItem,但它在第一次调用时返回null,并且仅在后续工作中正常工作 OnDropDownOpened 调用。我必须在调用之前添加UpdateLayout() ContainerFromItem,然后它也开始工作第一次电话。我知道替代解决方案是关闭虚拟化使用 VirtualizingStackPanel 但出于性能原因,我不想这样做。 - JustAMartin


根据我的研究, UpdateLayout 似乎是一种非常有力的方法来让布局上的所有控件都更新。但是,在大多数情况下,布局系统足够智能且足够快,可以自行更新。我读过的所有内容都让我相信只有在你进行大量的布局修改(添加控件并移动它们)时才需要这个调用,并且你需要显示一个特定的布局场景,而更新堆栈的其余部分是完成(但我还没有看到一个很好的例子来显示这个...正常的布局算法似乎就是那么好)。 这篇关于布局的MSDN文章 应该有助于澄清事情。

但是,从上面来看:

UpdateLayout方法强制进行递归布局更新,并且是   经常没必要

这个文件

经常调用InvalidateArrange,特别是UpdateLayout,   如果有大量元素,会产生重大的性能影响   存在于UI中。除非你绝对禁止调用此方法   需要精确的布局状态,以便随后调用其他API   你的代码。

最后直接回答你的问题。这主要是通过内部UI布局逻辑自行完成的,您很可能永远不需要使用它。通过上面的描述,在我看来,当你需要使用它时它会非常明显(并且它不适合那么多的线程,包括我自己曾经想过的)


3
2018-03-28 13:45



嗯......我仍然不明白你的例子。我尝试了你的代码,在Thread.Sleep()之前调用UpdateLayout()之后UI不会更新,它与调用方法没有区别。 - King Chan
@KingChan我完全更新了我的答案。经过大量研究后,看起来它看起来甚至是什么东西都认为是错误的。这是一种主要用于更新整个画布的方法......但几乎不需要。 - Justin Pihony
thansk为你的研究,所以现在我知道我们不需要那种方法来修复布局实际上很正常。谢谢。 +1 - King Chan


我认为在构建控件时最常用。例如:如果在代码中您感觉添加了新控件或发生了某些特定事件,您可以调用此UpdateLayout()来强制重新布局控件。在某些情况下,WPF可能会认为UI已经足够变化,因此它会自动调用控件的UpdateLayout()。我们都犯错误......如果你发现一个控件应该“重绘”或“重新排列”它的孩子,你可以尝试通过调用它的“UpdateLayout”强制它“刷新”。


0
2018-03-28 13:43