2

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

Q.1 - 我很困惑该使用哪一个。

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

Q.2 - 所有这 4 个东西看起来都很相似,但不知道什么时候使用哪一个?

4

1 回答 1

9

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

AffectsMeasure和之间的区别AffectsArrange只是一个导致对UIElement.InvalidateMeasure的调用(“影响布局的测量传递”),另一个导致对UIElement.InvalidateArrange的调用(“影响布局的排列传递”)。

从UIElement.Measure的备注中可以清楚地看出区别:

当一个布局第一次被实例化时,它总是在 Arrange 之前收到一个 Measure 调用。但是,在第一次布局传递之后,它可能会收到没有 Measure 的 Arrange 调用;当仅影响 Arrange 的属性发生更改(例如对齐)时,或者当父级收到没有 Measure 的 Arrange 时,可能会发生这种情况。Measure 调用将自动使 Arrange 调用无效。

并来自UIElement.InvalidateMeasure中的备注:

调用该方法内部也会调用InvalidateArrange,无需依次调用InvalidateMeasure和InvalidateArrange


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

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

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

InvalidateVisual中:

此方法在内部调用 InvalidateArrange。

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

于 2013-01-19T13:05:17.637 回答