【问题标题】:How do I measure the size of a TextBlock in WPF before it is rendered?如何在呈现之前测量 WPF 中 TextBlock 的大小?
【发布时间】:2010-06-07 10:18:04
【问题描述】:

我有一个带有两个 TextBlock 控件(堆叠)的 WPF DataTemplate,然后是下面的一些其他元素。由于一些复杂的布局代码,我需要知道两个TextBlock元素的高度,以便我可以画一些花哨的连接线,以及排列其他控件等。

如果我知道要进入 TextBlock 的文本,并且我知道字体等,是否有某种方法可以计算或测量这些 TextBlock 的高度而无需实际渲染它们?

【问题讨论】:

    标签: wpf textblock measure


    【解决方案1】:

    我认为调用UIElement.Measure(Size) 方法并随后检查UIElement.DesiredSize 属性就足够了。有关详细信息,请查看提供的 MSDN 链接。

    【讨论】:

    • +1,但请注意,除了通常的字体和字体大小之外,还有一个(继承的)附加属性,affects font hinting(是否与整个像素对齐),这会影响文本的宽度。附加属性是TextOptions.FormattingMode - 确保您正在测量的对象上的此属性的值与您正在渲染的对象上的值匹配(如果它们不相同)。
    • 刚刚遇到同样的问题,只是打电话给textblock.Measure(new Size()); 还不够。我必须使用textblock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 来获得textblock.DesiredSize 的结果
    • 记住,MinWidth 需要设置为 0,MaxWidth 在测量前设置为 PositiveInfinity,否则会被这些值限制。
    • 一定有别的东西,我得到了 DesiredSize.Height = 4.0。不是我要查找的内容,也不是屏幕上显示的内容。
    • 我还必须将 textBlock.Width 和 textBlock.Height 设置为 double.NaN,然后​​进行测量。
    【解决方案2】:

    对UIElement.Measure(Size) 的调用,将Size 作为参数。第二次调用 UIElement.DesiredSize 返回您传递给 Measure 方法的任何 Size。

    我认为是这样,因为UIElement(在这种情况下为TextBlock)还不是任何控件的子级,因此DesiredSize 没有任何不同的理由。

    【讨论】:

    • 不,不一定。即使没有将 UIElement(在我的情况下也是 TextBlock)添加到父控件,在我使用足够大的可用大小作为参数调用 Measure 之后,DesiredSize 也被正确设置。
    【解决方案3】:

    我很欣赏这是一个相当古老的问题,但我发现使用以下代码

            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}。 希望这对某人有所帮助。

    【讨论】:

      【解决方案4】:
      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);
      }
      

      【讨论】:

        【解决方案5】:

        由于 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2011-08-04
          • 2011-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-23
          • 1970-01-01
          相关资源
          最近更新 更多