影响测量或影响范围

我正在创建自定义控件,如果其中一个Dependency属性更改,我需要更新布局。 我可以使用FrameworkMetadataProperty.AffectsMeasureFrameworkMetadataProperty.AffectsArrange

问题1 – 我很困惑使用哪一个。

此外,我还可以使用UpdateLayout和InvalidateVisual方法来更新UI。

Q.2 – 所有这4件事看起来都很相似,并且在使用哪一件时感到困惑?

首先,将FrameworkPropertyMetadataOptions和调用方法设置为UpdateLayout或InvalidateVisual之间的区别是显而易见的。 在后一种情况下,您可以在控制代码中调用这些方法,在前一种情况下,框架会调用适当的方法。

AffectsMeasureAffectsArrange之间的区别很简单,一个是调用UIElement.InvalidateMeasure (“影响布局的度量传递”),另一个导致调用UIElement.InvalidateArrange (“影响布局的排列传递”) )。

从UIElement的备注中可以看出差异。测量:

首次实例化布局时,它始终在安排之前接收测量调用。 但是,在第一次布局传递之后,它可以接收没有测量的编配呼叫; 当仅影响排列的属性发生更改(例如对齐)或父级接收不带度量的排列时,就会发生这种情况。 Measure呼叫将自动使Arrange呼叫无效。

并从UIElement.InvalidateMeasure中的备注:

调用此方法也会在内部调用InvalidateArrange,无需连续调用InvalidateMeasure和InvalidateArrange


更新:有关UpdateLayout和InvalidateVisual之间的区别,请参阅UpdateLayout中的备注:

当您调用此方法时,IsMeasureValid为false或IsArrangeValid为false的元素将调用特定于元素的MeasureCore和ArrangeCore方法,这会强制进行布局更新,并且将validation所有计算的大小。

如果布局未更改,或者布局的布局和测量状态均无效,则调用此方法无效。 但是,如果布局在任何方面都无效,则UpdateLayout调用将重做整个布局。 因此,您应该避免在元素树中的每次增量和次要更改后调用UpdateLayout。 布局系统将使用平衡性能和货币的算法以延迟方式执行元素布局,并使用加权策略将更改推迟到根,直到所有子元素都有效。 如果您绝对需要更新大小和位置,并且只有在确定已完成对您控制且可能影响布局的属性的所有更改之后,才应调用UpdateLayout。

并在InvalidateVisual中 :

此方法在内部调用InvalidateArrange。

通常不会从应用程序代码中调用此方法。 WPF框架级布局系统自己处理元素可视树中的更改,并且在必要时将调用此方法的等效方法。 只有高级方案才需要调用此方法。 一个这样的高级方案是,如果要为不在Freezable或FrameworkElement派生类上的依赖项属性创建PropertyChangedCallback,该类在更改时仍会影响布局。