【问题标题】:Size RichTextBox according to contents根据内容调整 RichTextBox 的大小
【发布时间】:2015-04-24 05:35:17
【问题描述】:

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

    [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 的控制台应用程序)

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    您看过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.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();
        }
    

    【讨论】:

    • @HansPassant:如果你在富文本框中关闭自动换行,它会起作用吗?
    • 没有。不知道你为什么看到别的东西。
    • @HansPassant:这对我来说也是个谜! (Win7 x64,.Net 4)。
    • 这是正确答案。小偏移是由于缺少richTextBox.Margin.Horizontal + SystemInformation.HorizontalResizeBorderThickness + SystemInformation.HorizontalScrollBarThumbWidth
    • @banging - 这是很好的信息。虽然,我不需要那个 Horizo​​ntalScrollBarThumbWidth,因为滚动条被禁用了。
    【解决方案2】:

    如this answer中所述,使用GetPreferredSize 要容易得多。那么你就不需要等待 ContentsResized 事件了,

    【讨论】:

      【解决方案3】:

      身高呢?
      我加了

      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);  
      }  
      

      【讨论】:

        猜你喜欢
        • 2014-04-29
        • 2011-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-09
        • 2010-09-14
        • 1970-01-01
        相关资源
        最近更新 更多