【问题标题】:Rich Text Box padding between text and border文本和边框之间的富文本框填充
【发布时间】:2010-05-26 14:45:52
【问题描述】:

是否可以在富文本框控件的文本和边框之间添加填充?

我尝试将富文本框停靠在面板内,并将其所有四个边的填充设置为 10,这实现了我想要的。除非富文本框的垂直滚动条也需要填充。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    RichTextBox 没有填充属性。

    可以通过将 RichTextBox 放在 Panel 中来实现快速而肮脏的填充,该面板与 RichTextBox 具有相同的BackColor 属性(通常为Color.White)。

    然后,将 RichTextBox 的 Dock 属性设置为 Fill,并使用 Panel 控件的 Padding 属性。

    【讨论】:

    • 不错的解决方案!为我工作
    • 为了获得完美的外观,请将 RichTextBox 的 BorderStyle 设置为“None”。
    • 这又快又脏,但它也会在滚动条周围留出空间,就我而言,看起来很奇怪。
    【解决方案2】:

    EM_GETRECTEM_SETRECT

    将这两者结合在一起,您可以做到这一点:

    …看起来像这样:

    我写了a small C# extension class 来结束这一切。

    使用示例:

    const int dist = 24;
    richTextBox1.SetInnerMargins(dist, dist, dist, 0);
    

    这会将内边距左、上和右设置为 24,将下边距设置为零。

    请注意,滚动时,上边距保持不变,如下所示:

    就我个人而言,这看起来“不自然”。我希望滚动时上边距也变为零。

    也许有一个解决方法……

    完整源代码

    根据要求:

    public static class RichTextBoxExtensions
    {
        public static void SetInnerMargins(this TextBoxBase textBox, int left, int top, int right, int bottom)
        {
            var rect = textBox.GetFormattingRect();
    
            var newRect = new Rectangle(left, top, rect.Width - left - right, rect.Height - top - bottom);
            textBox.SetFormattingRect(newRect);
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public readonly int Left;
            public readonly int Top;
            public readonly int Right;
            public readonly int Bottom;
    
            private RECT(int left, int top, int right, int bottom)
            {
                Left = left;
                Top = top;
                Right = right;
                Bottom = bottom;
            }
    
            public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom)
            {
            }
        }
    
        [DllImport(@"User32.dll", EntryPoint = @"SendMessage", CharSet = CharSet.Auto)]
        private static extern int SendMessageRefRect(IntPtr hWnd, uint msg, int wParam, ref RECT rect);
    
        [DllImport(@"user32.dll", EntryPoint = @"SendMessage", CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam);
    
        private const int EmGetrect = 0xB2;
        private const int EmSetrect = 0xB3;
    
        private static void SetFormattingRect(this TextBoxBase textbox, Rectangle rect)
        {
            var rc = new RECT(rect);
            SendMessageRefRect(textbox.Handle, EmSetrect, 0, ref rc);
        }
    
        private static Rectangle GetFormattingRect(this TextBoxBase textbox)
        {
            var rect = new Rectangle();
            SendMessage(textbox.Handle, EmGetrect, (IntPtr) 0, ref rect);
            return rect;
        }
    }
    

    【讨论】:

    • 我喜欢这个答案。最好的回应。
    【解决方案3】:

    我遇到了同样的问题,所描述的答案对我没有帮助,这对我有用,所以如果有帮助,我会分享它。

    richTextBox1.SelectAll();
    richTextBox1.SelectionIndent += 15;//play with this values to match yours
    richTextBox1.SelectionRightIndent += 15;//this too
    richTextBox1.SelectionLength = 0;
    //this is a little hack because without this
    //i've got the first line of my richTB selected anyway.
    richTextBox1.SelectionBackColor = richTextBox1.BackColor;
    

    【讨论】:

    • 为了避免黑客攻击,您可以使用richTextBox1.DeselectAll();
    【解决方案4】:

    一种快速简便的方法是从垂直滚动中偏移文本,方法是在表单加载和表单/控件调整大小事件时调用此示例方法:

    private void AdjustTextBoxRMargin()
    {
        richTextBox1.RightMargin = richTextBox1.Size.Width - 35;
    }
    

    35 的值似乎适用于 Win7,但在其他版本的 Windows 上可能会有所不同。

    【讨论】:

      【解决方案5】:

      因为 RichTextBox 没有填充属性。您可以像本文中的那样创建自己的 RichTextBoxSubclass:

      http://www.codeproject.com/Articles/21437/A-Padded-Rich-Text-Box-Subclass

      【讨论】:

        【解决方案6】:

        在控制模板中的内容部分是这样的:

        <ScrollViewer x:Name="PART_ContentHost" 
                      Style="{StaticResource ScrollViewerTextBox}"
                      VerticalAlignment="Top"/>`
        

        为滚动查看器创建样式(和控件模板);将 Grid 列上的 MinWidth 设置为类似于滚动条的宽度,并在 ScrollContentPresenter 上将边距调整为您的偏好。

        <Style x:Key="ScrollViewerTextBox" TargetType="{x:Type ScrollViewer}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ScrollViewer}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition Width="Auto" MinWidth="18"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <ScrollContentPresenter Grid.Column="0" Margin="3 3 3 0" CanVerticallyScroll="True" CanContentScroll="True"/>
                            <ScrollBar x:Name="PART_VerticalScrollBar" 
                                       Grid.Row="0" 
                                       Grid.Column="1"
                                       Value="{TemplateBinding VerticalOffset}" 
                                       Maximum="{TemplateBinding ScrollableHeight}" 
                                       ViewportSize="{TemplateBinding ViewportHeight}" 
                                       Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}">
                                <ScrollBar.ContextMenu>
                                    <ContextMenu Visibility="Hidden" />
                                </ScrollBar.ContextMenu>
                            </ScrollBar>
                            <ScrollBar x:Name="PART_HorizontalScrollBar" 
                                       Orientation="Horizontal" 
                                       Grid.Row="1" 
                                       Grid.Column="0" 
                                       Value="{TemplateBinding HorizontalOffset}" 
                                       Maximum="{TemplateBinding ScrollableWidth}" 
                                       ViewportSize="{TemplateBinding ViewportWidth}" 
                                       Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}">
                                <ScrollBar.ContextMenu>
                                    <ContextMenu Visibility="Hidden" />
                                </ScrollBar.ContextMenu>
                            </ScrollBar>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        

        【讨论】:

          【解决方案7】:

          也许这就是你需要的?

          richTextBox.SelectionIndent += 20;
          

          【讨论】:

          • 为此,您不必先选择要缩进的文本吗?我知道你可以在代码中做到这一点,但如果他必须在添加到 RTB 的每一行文本上选择并设置缩进,这似乎不是一个很好的答案来满足 OP 的需求
          • 不,您不需要为此选择文本!干得好菲尔。你不会碰巧知道如何设置顶部和底部边距?
          【解决方案8】:

          这里有一个更简单的答案。它不可自定义,但会在整个文本周围放置一个小填充 - 顶部、底部、左侧和右侧。

          在设计时,设置 RichTextBox 的 ShowSelectionMargin 属性 到True。运行时,您可能会注意到正在应用的边距(从无边距到边距),看起来有点“抖动”。如果是这样,请在加载 RichTextBox 之前添加一个Me.SuspendLayout,并在加载后添加一个Me.ResumeLayout

          【讨论】:

            【解决方案9】:

            这是一个简单的解决方案,用于设置 RichTextBox 的左右边距,在 C# Windows 应用程序中对我来说效果很好。它将右边距和左边距都设置为 4 像素。

            [DllImport("user32.dll")]
            static extern int SendMessage(IntPtr hWnd, uint wMsg, UIntPtr wParam, IntPtr lParam);
            
            // both left and right margins set to 4 pixels with the last parm: 0x00040004
            SendMessage(richtextbox1.Handle, 0xd3, (UIntPtr)0x3, (IntPtr)0x00040004);
            

            我试图在下面使 SendMessage 更合适:

            const int EM_SETMARGINS = 0xd3;
            const int EC_LEFTMARGIN = 0x1;
            const int EC_RIGHTMARGIN = 0x2;
            
            SendMessage(richtextbox1.Handle, EM_SETMARGINS,
             (UIntPtr)(EC_LEFTMARGIN | EC_RIGHTMARGIN), (IntPtr)0x00040004);
            

            我认为这个问题最初发布时是不可能的。

            【讨论】:

              【解决方案10】:

              也许您正在寻找缩进文本?像左右缩进一样? 如果是这样,那么您可以只使用 rtf 对象的 ReGETIndent 和 ReSetIndent 方法。

              这是我的工作:

              //first I find the length of the active window
              
              nLen := REGEtIndent( ::oActive:hWnd )    
              //now resetIndents of the rtf control    
              RESetIndent( ::oActive:hWnd, nLen[ 1 ] + 100, nLen[ 2 ] + 100, -25 )
              

              希望对您有所帮助。

              【讨论】:

                【解决方案11】:

                将右侧的填充设置为0,然后将RichTextBox的RightMargin设置为10。未测试,但应该可以。

                【讨论】:

                • RichTextBox 没有填充
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-06-21
                • 2017-11-16
                • 2011-11-08
                • 2015-07-26
                • 1970-01-01
                • 1970-01-01
                • 2013-01-21
                相关资源
                最近更新 更多