【发布时间】:2010-06-07 10:18:04
【问题描述】:
我有一个带有两个 TextBlock 控件(堆叠)的 WPF DataTemplate,然后是下面的一些其他元素。由于一些复杂的布局代码,我需要知道两个TextBlock元素的高度,以便我可以画一些花哨的连接线,以及排列其他控件等。
如果我知道要进入 TextBlock 的文本,并且我知道字体等,是否有某种方法可以计算或测量这些 TextBlock 的高度而无需实际渲染它们?
【问题讨论】:
我有一个带有两个 TextBlock 控件(堆叠)的 WPF DataTemplate,然后是下面的一些其他元素。由于一些复杂的布局代码,我需要知道两个TextBlock元素的高度,以便我可以画一些花哨的连接线,以及排列其他控件等。
如果我知道要进入 TextBlock 的文本,并且我知道字体等,是否有某种方法可以计算或测量这些 TextBlock 的高度而无需实际渲染它们?
【问题讨论】:
我认为调用UIElement.Measure(Size) 方法并随后检查UIElement.DesiredSize 属性就足够了。有关详细信息,请查看提供的 MSDN 链接。
【讨论】:
TextOptions.FormattingMode - 确保您正在测量的对象上的此属性的值与您正在渲染的对象上的值匹配(如果它们不相同)。
textblock.Measure(new Size()); 还不够。我必须使用textblock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 来获得textblock.DesiredSize 的结果
MinWidth 需要设置为 0,MaxWidth 在测量前设置为 PositiveInfinity,否则会被这些值限制。
对UIElement.Measure(Size) 的调用,将Size 作为参数。第二次调用 UIElement.DesiredSize 返回您传递给 Measure 方法的任何 Size。
我认为是这样,因为UIElement(在这种情况下为TextBlock)还不是任何控件的子级,因此DesiredSize 没有任何不同的理由。
【讨论】:
我很欣赏这是一个相当古老的问题,但我发现使用以下代码
TextBlock textBlock = new TextBlock();
textBlock.Text = "NR valve";
Size msrSize = new Size(100, 200);
textBlock.Measure(msrSize);
Size dsrdSize = textBlock.DesiredSize;
dsrdSize 返回为 {47.05,15.96}。 诀窍似乎是使 msrSize 大于预期的实际大小。 msrSize 似乎充当了 DesiredSize() 结果的限制。 例如,使用 msrSize = new Size(10, 10),此处的 dsrdSize 为 {10,10}。 希望这对某人有所帮助。
【讨论】:
public static Size ShapeMeasure(TextBlock tb) {
// Measured Size is bounded to be less than maxSize
Size maxSize = new Size(
double.PositiveInfinity,
double.PositiveInfinity);
tb.Measure(maxSize);
return tb.DesiredSize;
}
public static Testit()
{
TextBlock textBlock = new TextBlock();
textBlock.Text = "NR valve";
Size text size = ShapeMeasure(textBlock);
}
【讨论】:
由于 Measure 是在 UIElement 中定义的,因此您可以测量任何 UIElement 派生对象的形状,包括 TextBlock:
public static Size ShapeMeasure(UIElement e) {
// Measured Size is bounded to be less than maxSize
Size maxSize = new Size(
double.PositiveInfinity,
double.PositiveInfinity);
e.Measure(maxSize);
return e.DesiredSize;
}
【讨论】: