2011-05-18 40 views
1

我需要计算显示文本的Windows窗体宽度。 形式宽度显然是在像素所以你只是想获得文本的宽度,以像素为单位,但是,这并不工作:计算显示文本的Windows窗体宽度

animationForm.Width = TextRenderer.MeasureText(_caption, animationForm.Font).Width; 

计算的表格宽度来说太小了(切断文本) - 这里发生了什么? MeasureText使用像素,表单宽度以像素为单位。

这工作好,但我不认为这是正确的:

animationForm.Width = (int)(_caption.Length * animationForm.Font.Size); 

帮助,将不胜感激。

AnimationPic - 图片框, 标题上一个标签组

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Threading; 
using System.Windows.Forms; 

namespace PrlSystems.MaimInvoicing.Forms 
{ 
    public partial class ProgressIndicatorForm : Form 
    { 
     private volatile bool _animating = false; 
     private Form _parent; 
     private string _caption = ""; 

     private object _mutex = new object(); 

     public ProgressIndicatorForm(Form parent) 
     { 
      InitializeComponent(); 
      _parent = parent; 
     } 

     public string Caption 
     { 
      set { _caption = value; } 
      get { return _caption; } 
     } 

     public void StartAnimation() 
     { 
      lock (_mutex) 
      { 
       if (!_animating) 
       { 
        if (_parent != null) 
        { 
         _parent.Cursor = Cursors.WaitCursor; 
         _parent.Enabled = false; 
        } 

        _animating = true; 
        _SpawnAnimationThread(); 
       } 
      } 
     } 

     public void StopAnimation() 
     { 
      lock (_mutex) 
      { 
       if (_animating) 
       { 
        _animating = false; // stop animation thread 

        if (_parent != null) 
        { 
         // restore parent form UI 
         _parent.Cursor = Cursors.Default; 
         _parent.Enabled = true; 
         _parent.Activate(); 
        } 
       } 
      } 
     } 

     private void _SpawnAnimationThread() 
     { 
      Thread animationThread = new Thread(new ThreadStart(_Animate)); 
      animationThread.Priority = ThreadPriority.Normal; 
      animationThread.IsBackground = true; // should terminate when application ends 
      animationThread.Start(); 
     } 

     private void _Animate() 
     { 
      ProgressIndicatorForm animationForm = new ProgressIndicatorForm(_parent); 
      animationForm.CaptionLabel.Text = _caption; 
      animationForm.StartPosition = FormStartPosition.CenterScreen; 
      animationForm.TopMost = true; 
      animationForm.Width = _CalculateFormWidth(animationForm); 

      animationForm.Show(); 

      while (_animating) 
      { 
       animationForm.CaptionLabel.Text = _caption; 
       animationForm.Width = _CalculateFormWidth(animationForm); 

       animationForm.BringToFront(); 
       animationForm.Refresh(); 
      } 
      animationForm.Close(); 
      animationForm.Dispose(); 
     } 

     private int _CalculateFormWidth(ProgressIndicatorForm animationForm) 
     { 
      int width = AnimationPic.Location.X + AnimationPic.Width + 
       TextRenderer.MeasureText(_caption, animationForm.Font).Width; 


      return width; 
     } 
    } 
} 

形象设计师:

This is how it looks in the designer, the progress dialog

+0

我要澄清一些我遗漏的东西,但这很重要。我也有动画片。以下是整个公式:int width = AnimationPic.Location.X + AnimationPic.Width + TextRenderer.MeasureText(_caption,animationForm.Font).Width; – ActiveX 2011-05-18 14:08:35

回答

0

您还需要考虑额外的尺寸,如宽度形成。标签周围的空间(如果您使用标签?)

+0

但绝对不要尝试手动执行此操作。使用为此目的明确提供的属性。 – 2011-05-18 13:58:57

+0

是的,我正在使用一个标签......文本的严重损失(是截断)告诉我还有其他错误。我上面发布了完整的代码。 – ActiveX 2011-05-18 15:05:37

4

而不是Form.Width,您需要使用Form.ClientSize.Width

后者将返回形式的客户区的实际宽度;即你可以画东西的地方。从文档中的备注部分:

窗体客户区的大小是窗体的大小,不包括边框和标题栏。表单的客户区域是可以放置控件的表单中的区域。您可以在执行图形操作时或在窗体上调整大小和定位控件时使用此属性来获取适当的尺寸。要获取整个表格的大小,请使用Size property或使用单个属性HeightWidth

对比度与Form.Width(或Form.Size.Width),因为它出现在屏幕上,包括在非客户区多余的东西,如窗口边界,它返回整个宽度的形式的。绝对不要浪费任何时间去手动计算和删除这些项目的尺寸;它已经为你完成了。


使用下面的代码:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    string longStringOfText = "This is a really long string of text we're using for testing purposes."; 

    // Resize the form's client area, keeping the same height, but 
    // changing the width to match that needed to draw the text. 
    this.ClientSize = new Size(TextRenderer.MeasureText(longStringOfText, 
                 this.Font).Width, 
           ClientSize.Height); 

    // Then draw in the text. 
    TextRenderer.DrawText(e.Graphics, 
          longStringOfText, 
          this.Font, 
          Point.Empty, 
          Color.Purple); 
} 

我得到这个:

Form, with text string correctly fit across it

看起来不错,我...

+0

Form.Width没有被调用,它被设置... – Frosty840 2011-05-18 13:59:57

+0

@Frosty:你的意思是什么?我是否使用“所谓”而不是“set”这个词?我的不好,我会解决它。当然,这一点仍然是一样的。您需要设置**客户区**的大小,而不是整个表单的大小(包括非客户区)。 – 2011-05-18 14:00:54

+0

伙计们,这是没有任何边界的动画对话框,所以它并不重要。不过,无论我是否使用客户区域,我仍然输(截止因为宽度太短)40%的文字。 – ActiveX 2011-05-18 14:01:46

0

您是否尝试过指定的设备上下文? 尝试使用此方法重载MeasureText(IDeviceContext, String, Font, Size)

当您使用Form.Width时,宽度也包含窗口边框的宽度。试试这个:

animationForm.ClientSize.Width = TextRenderer.MeasureText(_caption, animationForm.Font).Width; 
+0

我很难想象这里的设备环境可能如何相关。 – 2011-05-18 13:58:35

+0

我试过了,没关系。 – ActiveX 2011-05-18 14:07:45

+0

是否将AnimationPic直接放置在表单上,​​还是放在某个容器中? – 2011-05-18 14:21:37