.net 计算显示文本的窗口窗体宽度

.net 计算显示文本的窗口窗体宽度,.net,winforms,forms,graphics,textrenderer,.net,Winforms,Forms,Graphics,Textrenderer,我需要为显示的文本计算Windows窗体宽度。 表单宽度显然是以像素为单位的,因此您只需要以像素为单位获取文本的宽度,但这不起作用: animationForm.Width = TextRenderer.MeasureText(_caption, animationForm.Font).Width; 计算的表单宽度太小(剪切文本)-这是怎么回事? MeasureText使用像素,表单宽度以像素为单位 这样做效果更好,但我认为这是不对的: animationForm.Width = (int)(

我需要为显示的文本计算Windows窗体宽度。 表单宽度显然是以像素为单位的,因此您只需要以像素为单位获取文本的宽度,但这不起作用:

animationForm.Width = TextRenderer.MeasureText(_caption, animationForm.Font).Width;
计算的表单宽度太小(剪切文本)-这是怎么回事? MeasureText使用像素,表单宽度以像素为单位

这样做效果更好,但我认为这是不对的:

animationForm.Width = (int)(_caption.Length * animationForm.Font.Size);
我们将不胜感激

AnimationPic-PictureBox, 标题设置在标签上

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;
        }
    }
}
设计器中的图像:


您还需要考虑额外的尺寸,例如表单的宽度。标签周围的空间(如果您正在使用标签?

您还需要考虑额外的大小,例如表单的宽度。标签周围的空格(如果您正在使用标签?

而不是
表单。宽度
,您需要使用

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

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

与之对比的是
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);
}
我明白了:


在我看来很不错…

而不是
表单。宽度
,您需要使用

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

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

与之对比的是
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);
}
我明白了:


看起来很不错…

您是否尝试过指定设备上下文? 尝试此方法重载
MeasureText(IDeviceContext、字符串、字体、大小)

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

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

您是否尝试过指定设备上下文? 尝试此方法重载
MeasureText(IDeviceContext、字符串、字体、大小)

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

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


我很难想象设备上下文与此相关。AnimationPic是直接放在表单上还是放在某个容器中?@ActiveX能否在设计模式下发送表单的屏幕截图?直接放在表单上。表单样式为FixedDialog,没有最大值、最小值、按钮等。如何在此处向您发送电子邮件?我不熟悉堆栈溢出。@ActiveX:您不需要电子邮件。您可以在问题中直接附加图像。有关详细信息,请参阅。我很难想象设备上下文与此相关。AnimationPic是直接放在表单上还是放在某个容器中?@ActiveX能否在设计模式下发送表单的屏幕截图?直接放在表单上。表单样式为FixedDialog,没有最大值、最小值、按钮等。如何在此处向您发送电子邮件?我不熟悉堆栈溢出。@ActiveX:您不需要电子邮件。您可以在问题中直接附加图像。有关详细信息,请参阅。但绝对不要尝试手动执行此操作。使用为此目的明确提供的属性。是的,我正在使用标签。。。文本的大量丢失(被切断)告诉我还有其他问题。我在上面发布了完整的代码。但绝对不要尝试手动执行此操作。使用为此目的明确提供的属性。是的,我正在使用标签。。。文本的大量丢失(被切断)告诉我还有其他问题。我在上面公布了全部代码。@Frosty:你的意思是什么?我是不是用了“called”而不是“set”?我的坏毛病,我会解决的。当然,这一点还是一样的。您需要设置客户端区域的大小,而不是整个表单(包括非客户端区域)的大小。伙计们,这是一个没有任何边界的动画对话框,所以这并不重要。然而,无论我是否使用客户端区域,我仍然丢失了40%的文本(因为宽度太短而被截断)。@ActiveX:我无法想象问题出在哪里。这对我来说非常有效。。。用您尝试过的涉及
ClientSize
属性的代码更新您的问题。我将澄清我遗漏的一些内容,但这很重要。我也有一个动画图片。下面是完整的公式:int-width=AnimationPic.Location.X+AnimationPic.width+textrender.MeasureText(_-caption,animationForm.Font).width;我已经在上面的原始帖子中发布了完整的代码。我只对宽度感兴趣,因为它只能改变。@Frosty:你的意思是什么?我是不是用了“called”而不是“set”?我的错,我会的