【问题标题】:Notification from parent to child that the position was changed从父母到孩子的位置改变的通知
【发布时间】:2012-07-23 11:41:22
【问题描述】:

我有一个自定义控件,需要通知父控件的布局更改。因此,如果父母重新安排孩子,我想计算新的视觉位置。不幸的是,不会调用子级上的ArrangeOverride,这是有道理的,因为子级控件内部的位置并没有真正改变。现在在布局过程中,我的自定义控件已正确定位,但未调用 ArrangeOverride。 为了让您更清楚地了解我想要实现的目标:我有一个控件,that blurs the background 提供类似航空玻璃的效果。为了实现这一点,我的控件将背景控件渲染到可视画笔中,并计算该画笔的视图框以使背景发光,然后通过模糊效果对其进行模糊处理。只要布局没有改变,它就可以正常工作。如果是这样,我需要更新画笔。我在 ArrangeOverride 方法中做到了这一点。

所以我尝试使用ArrangeOverrideMeasureOverride、Invalidating 或 Parent 失效的各种组合。起初我继承自ContentControl,但将其更改为Decorator,认为装饰器可能有一些特殊行为无用。我想尽可能避免LayoutChanged,因为这是一个非常非常邪恶的事件。我会给你一些代码,但它没有什么特别之处,我认为这是一个相当基本的问题,并没有真正绑定到我的代码。顺便说一下,布局器可以是任何东西(不仅仅是画布)。 那么我必须通过什么事件、方法或方式来了解父母告诉我的控件“我知道你没有改变任何东西,但我确实重新定位了你”。

【问题讨论】:

  • 不确定,但这对您有帮助吗? - 最后一个子填充的停靠面板
  • 你在孩子身上试过LayoutUpdated事件吗?
  • @Clemens 好吧,是的,这是我想采取的最后一个选择。因为就像我写了一个非常邪恶的事件,你永远不应该使用我仍然不知道微软为什么保留它,或者为什么他们以他们的方式实施它。简而言之,当任何控件更新时都会触发此事件。因此,如果您在某处有动画或鼠标悬停效果,则无论您在何处注册此事件,它都会随时调用。
  • 刚刚使用 Canvas 上的派生形状做了一个非常基本的测试。它表明每当子位置发生变化时都会调用ArrangeOverride(此处为 Canvas.Left/Top)。据我了解安排机制,每个父母必须在其所有孩子上调用Arrange,这导致在每个孩子中调用ArrangeOverride

标签: c# wpf


【解决方案1】:

所以我以一种我不太满意的方式对其进行了修复,但它解决了许多其他不必要的问题,只是为了让它工作,比如当模糊控件本身被动画时。因此,无论发生什么,这个解决方案现在都适用。虽然我避免了 LayoutUpdated 事件,但我使用了类似的“邪恶”事件。 CompositionTarget.Rendering 所以在Loaded 事件中,我注册到渲染事件,在Unloaded 我从渲染事件中注销。这样,LoadedUnloaded 被调用的频率并不重要。在渲染事件本身中,我只是触发了我的 VisualBrush.Viewbox 失效代码。这工作得很好,即使事件被触发了很多。我不怎么使用模糊,所以它不会对性能产生太大影响......现在。

【讨论】:

  • 但是CompositionTarget.Rendering 的调用频率远远高于LayoutUpdated,或者更准确地说,它在每一帧上都被调用,这通常意味着每秒60 次。当你谈论邪恶时,这真的是邪恶的。
  • @Clemens 我完全同意,我认为这只是我的愚蠢迷信,为什么我现在更喜欢它而不是 layoutchanged。如果您发布有关 LayoutUpdated 事件的评论,我会将其标记为答案,因为不给您它是不公平的,只是因为我使用了另一个类似的事件。
  • 有没有答案不是重点。我只是相信你应该继续找出为什么你的ArrangeOverride 没有被调用。一定是有原因的。我也非常不喜欢LayoutUpdated,所以我不会写这个作为答案。
  • 我同意,但不幸的是我的老板和我的截止日期告诉我不是这样;)。但我不是那种会留下这样的人......我稍后会检查它,当然我会在这里更新这个帖子,让每个人都知道。
猜你喜欢
  • 2022-12-16
  • 2013-07-25
  • 2019-11-24
  • 2014-08-08
  • 2017-07-01
  • 2021-08-17
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
相关资源
最近更新 更多