根据内容调整RichTextBox的大小

时间:2012-08-10 18:02:32

标签: c# winforms

此代码根据其内容自动调整RichTextBox的大小。我遇到了问题,尤其是桌子。 \t可能会被忽略。我尝试了托管解决方案,现在我正在尝试平台调用。电流输出:

enter image description here

    [DllImport("gdi32.dll")]
    static extern bool GetTextExtentPoint32(IntPtr hdc, string lpString, int cbString, out SIZE lpSize);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr GetDC(IntPtr hWnd);

    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct SIZE
    {
        public int cx;
        public int cy;

        public SIZE(int cx, int cy)
        {
            this.cx = cx;
            this.cy = cy;
        }
    }

    public static void Main()
    {
        Form form = new Form();
        RichTextBox rtfBox = new RichTextBox();

        rtfBox.Rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Arial;}}\viewkind4\uc1\trowd\trgaph100\cellx1000\cellx2000\pard\intbl\lang1033\f0\fs20  hi\cell  bye\cell\row\intbl  one\cell  two\cell\row\pard\par}";
        rtfBox.ScrollBars = RichTextBoxScrollBars.None;

        string sInput = "hi\t bye\t\n";// one\t two\t\n";
        SIZE CharSize;

        form.Controls.Add(rtfBox);

        IntPtr hdc = GetDC(IntPtr.Zero);//Context for entire screen
        GetTextExtentPoint32(hdc, sInput, sInput.Length, out CharSize);

        rtfBox.Width = CharSize.cx;
        rtfBox.Height = CharSize.cy;

        form.Visible = false;

        form.ShowDialog();
    }

(注意,为简单起见,这是一个引用System.Windows.Forms.dll的控制台应用程序)

3 个答案:

答案 0 :(得分:13)

你看过ContentsResized事件了吗?添加以下方法以在事件触发时调用:

private void richTextBox_ContentsResized(object sender, ContentsResizedEventArgs e)
{
    var richTextBox = (RichTextBox) sender;
    richTextBox.Width = e.NewRectangle.Width;
    richTextBox.Height = e.NewRectangle.Height;
}

当更改RTF内容时(使用Rtf),应调整RichTextBox的大小以匹配其内容。确保您还将WordWrap属性设置为false


我已经尝试过你的表示例,它看起来确实有效(虽然有一点偏移,你可以通过在调整后的大小上添加一些宽度的像素来解决 - 不知道为什么会发生这种情况):< / p>

P.Brian.Mackey编辑
这个答案对我有用。为了澄清,这里是最终的代码,包括边界修复:

    public static void Main()
    {
        string sInput = "hi\t bye\t\n";// one\t two\t\n";
        SIZE CharSize;
        Form form = new Form();
        RichTextBox rtfBox = new RichTextBox();
        rtfBox.ContentsResized += (object sender, ContentsResizedEventArgs e) =>
        {
            var richTextBox = (RichTextBox)sender;
            richTextBox.Width = e.NewRectangle.Width;
            richTextBox.Height = e.NewRectangle.Height;
            rtfBox.Width += rtfBox.Margin.Horizontal + SystemInformation.HorizontalResizeBorderThickness;
        };

        rtfBox.WordWrap = false;
        rtfBox.ScrollBars = RichTextBoxScrollBars.None;

        rtfBox.Rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Arial;}}\viewkind4\uc1\trowd\trgaph100\cellx1000\cellx2000\pard\intbl\lang1033\f0\fs20  hi\cell  bye\cell\row\intbl  one\cell  two\cell\row\pard\par}";

        form.Controls.Add(rtfBox);
        form.ShowDialog();
    }

答案 1 :(得分:2)

如本答案中所述,使用GetPreferredSize要容易得多。然后您不需要等待ContentsResized事件,

答案 2 :(得分:0)

高度怎么样?
我添加了

richTextBox.Height += richTextBox.Margin.Vertical +  
SystemInformation.VerticalResizeBorderThickness;  

最后。

它看起来也是扩展方法的一个很好的候选者:

static public class RichTextBoxResizer {  
    static public void ResizeToContents(this RichTextBox richTextBox, ContentsResizedEventArgs e) {  
        richTextBox.Width = e.NewRectangle.Width;  
        richTextBox.Height = e.NewRectangle.Height;  

        richTextBox.Width += richTextBox.Margin.Horizontal +  
            SystemInformation.HorizontalResizeBorderThickness +  
            SystemInformation.HorizontalScrollBarThumbWidth;  

        richTextBox.Height += richTextBox.Margin.Vertical +  
            SystemInformation.VerticalResizeBorderThickness;  
    }   

    static public void ResizeToContentsHorizontally(this RichTextBox richTextBox, ContentsResizedEventArgs e) {
        richTextBox.Width = e.NewRectangle.Width;

        richTextBox.Width += richTextBox.Margin.Horizontal +
            SystemInformation.HorizontalResizeBorderThickness +
            SystemInformation.HorizontalScrollBarThumbWidth;
    }

    static public void ResizeToContentsVertically(this RichTextBox richTextBox, ContentsResizedEventArgs e) {
        richTextBox.Height = e.NewRectangle.Height;

        richTextBox.Height += richTextBox.Margin.Vertical +
            SystemInformation.VerticalResizeBorderThickness;
    }
}

所以事件接收器看起来像:

private void rtfBox_ContentsResized(object sender, ContentsResizedEventArgs e) {  
    RichTextBox rtb = (RichTextBox)sender;  
    rtb.ResizeToContents(e);  
}