如何设置 UIElement 的 DesiredSize.Width?

Posted

技术标签:

【中文标题】如何设置 UIElement 的 DesiredSize.Width?【英文标题】:How to set DesiredSize.Width of a UIElement? 【发布时间】:2010-12-21 17:40:16 【问题描述】:

我需要在自定义面板中计算每个UIElementWidth。如果循环遍历Children:

foreach (UIElement child in Children)  ... 

child.DesiredSize.Width = myCalculatedWidth; 我不能这样做,因为DesiredSizeDesiredSize.Width 是只读的。

文档说Measure() 更新了UIElementDesiredSize,所以我尝试了:

Size size = new Size(myCalculatedWidth, Double.PositiveInfinity);
child.Measure(size);

但是child.DesiredSize.Width 没有改变。如何设置DesiredSize.Width

【问题讨论】:

【参考方案1】:

试试child.Width = myCalculatedWidth

【讨论】:

UIElement 没有 Width 属性。【参考方案2】:

致电InvalidateArrange()。渲染系统将调用Arrange(Rect) 并根据您的尺寸更新UIElement 的DesiredSize

【讨论】:

【参考方案3】:

如果您直接调用Measure,则WPF 布局系统将无事可做(因为它会缓存控件的状态并将其存储为MeasureIsValid 之类的标志)。您应该为此控件调用InvalidateMeasure()(这会将控件标记为MeasureIsValid = false)UpdateLayout(),然后强制更新布局。

【讨论】:

【参考方案4】:

其他答案都不适合我。我需要做的是在子控件中实现MeasureOverride,并在那里实现所需的布局行为。

【讨论】:

【参考方案5】:

不能直接更改 DesiredSize,因为只有 UIElement 可以写入 DesiredSize,这发生在 UIElement.Measure()。但是,Measure() 不计算 DesiredWidth,而是调用 MeasurementCore。但是即使是MeasurementCore也不是直接计算DesiredSize,而是使用MeasurementOverride的retunr值。这就是您必须覆盖 MeasurementOverride() 以更改 DesiredChange 的原因:-)

看起来像这样:

UIElement.Measure() calls 
  FrameworkElement.MeasureCore() calls
    YourControl.MeasureOverwrite()

MeasureOverwrite()的返回值成为MeasureCore()的返回值,然后存储在UIElement.DesiredSize中。

请注意,MeasureOverwrite() 返回的值不一定与存储在 DesiredSize 中的值相同,因为 Margin 会添加到返回值中! FrameworkElement.MeasurementCore() 还确保 DesiredSize 分别在 MinWidth、MaxWidth 和 Height 范围内。如果返回值为isNaN的Width或Height为Infinite,则抛出异常。

【讨论】:

以上是关于如何设置 UIElement 的 DesiredSize.Width?的主要内容,如果未能解决你的问题,请参考以下文章

如何快速复制 UIElement?

如何以相同的触摸在多个 UIElement 上触发 ManipulationStarted?

如何自动在标签中放入 UIElement 的名称

拖动某些东西时如何在 UIElement 周围显示一个简单的边框

我可以更改 UiPath.Core.UiElement 中的属性值吗

Silverlight 4 - 将 UIElement 渲染为图像