20

有什么方法可以更改 .NET RichTextBox 中的默认选项卡大小?它目前似乎设置为相当于 8 个空格,这对我来说有点大。

编辑:为了澄清,我想将“\t”的全局默认设置为控件的 4 个空格。据我了解, SelectionTabs 属性要求您首先选择所有文本,然后通过数组选择选项卡宽度。如果必须,我会这样做,但如果可能的话,我宁愿只更改一次全局默认值,这样我就不必每次都这样做。

4

5 回答 5

24

您可以通过设置SelectionTabs属性来设置它。

private void Form1_Load(object sender, EventArgs e)
{
    richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };
}

更新:
顺序很重要....

如果在初始化控件文本之前设置选项卡,则不必在设置选项卡之前选择文本。

例如,在上面的代码中,这将保留带有原始 8 个空格制表位的文本:

richTextBox1.Text = "\t1\t2\t3\t4";
richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };

但这将使用新的:

richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };
richTextBox1.Text = "\t1\t2\t3\t4";
于 2008-09-30T18:09:37.970 回答
5

Winforms 没有使用单个数字设置 RichTexBox 的默认选项卡大小的属性,但是如果您准备深入研究富文本框的 Rtf 并对其进行修改,则可以使用以下设置: “\deftab”。后面的数字表示缇的数量(1 点 = 1/72 英寸 = 20 缇)。标准制表符大小为 720 缇的 Rtf 可能类似于:

{\rtf1\ansi\ansicpg1252\deff0\deflang2057\deftab720{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
\viewkind4\uc1\pard\f0\fs41
1\tab 2\tab 3\tab 4\tab 5\par
}

如果您需要将缇转换为像素,请使用受Convert Pixels to Points启发的代码:

int tabSize=720;
Graphics g = this.CreateGraphics();
int pixels = (int)Math.Round(((double)tabSize) / 1440.0 * g.DpiX);
g.Dispose();
于 2012-01-09T10:29:26.600 回答
3

奇怪的是一直没有人提出这种方法)

我们可以继承RichTextBox并重写 CmdKey 处理程序(ProcessCmdKey
它看起来像这样:

public class TabRichTextBox : RichTextBox
{
    [Browsable(true), Category("Settings")]
    public int TabSize { get; set; } = 4;

    protected override bool ProcessCmdKey(ref Message Msg, Keys KeyData)
    {
            
        const int WM_KEYDOWN = 0x100;       // https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keydown
        const int WM_SYSKEYDOWN = 0x104;    // https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-syskeydown
        // Tab has been pressed
        if ((Msg.Msg == WM_KEYDOWN || Msg.Msg == WM_SYSKEYDOWN) && KeyData.HasFlag(Keys.Tab))
        {
            // Let's create a string of spaces, which length == TabSize
            // And then assign it to the current position
            SelectedText += new string(' ', TabSize);

            // Tab processed
            return true;
        }
        return base.ProcessCmdKey(ref Msg, KeyData);
    }
}

现在,当您按下 时Tab,将在控制区域中插入指定数量的空格,而不是\t

于 2018-08-31T21:10:57.083 回答
1

如果您有一个仅用于显示(只读)固定间距文本的 RTF 框,那么最简单的方法就是不要乱用制表位。只需用空格替换它们。

如果您希望用户可以输入某些内容并使用该 Tab 键前进,您还可以通过覆盖OnKeyDown()和打印空格来捕获 Tab 键。

于 2013-08-23T09:36:03.100 回答
0

我正在使用带有等宽字体的此类;它将所有 TAB 替换为空格。

您所要做的就是根据您的要求设置以下设计器属性:

  • AcceptsTab = True TabSize
  • ConvertTabToSpaces = True
  • 选项卡大小 = 4

PS:正如@ToolmakerSteve 所指出的,显然这里的制表符大小逻辑非常简单:它只是用 4 个空格替换制表符,这仅适用于每行开头的制表符。如果您需要改进选项卡处理,只需扩展逻辑即可。

代码

using System.ComponentModel;
using System.Windows.Forms;

namespace MyNamespace
{
    public partial class MyRichTextBox : RichTextBox
    {
        public MyRichTextBox() : base() =>
            KeyDown += new KeyEventHandler(RichTextBox_KeyDown);

        [Browsable(true), Category("Settings"), Description("Convert all tabs into spaces."), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public bool ConvertTabToSpaces { get; set; } = false;

        [Browsable(true), Category("Settings"), Description("The number os spaces used for replacing a tab character."), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int TabSize { get; set; } = 4;

        [Browsable(true), Category("Settings"), Description("The text associated with the control."), Bindable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public new string Text
        {
            get => base.Text;
            set => base.Text = ConvertTabToSpaces ? value.Replace("\t", new string(' ', TabSize)) : value;
        }

        protected override bool ProcessCmdKey(ref Message Msg, Keys KeyData)
        {
            const int WM_KEYDOWN = 0x100; // https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keydown
            const int WM_SYSKEYDOWN = 0x104; // https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-syskeydown

            if (ConvertTabToSpaces && KeyData == Keys.Tab && (Msg.Msg == WM_KEYDOWN || Msg.Msg == WM_SYSKEYDOWN))
            {
                SelectedText += new string(' ', TabSize);
                return true;
            }
            return base.ProcessCmdKey(ref Msg, KeyData);
        }

        public new void AppendText(string text)
        {
            if (ConvertTabToSpaces)
                text = text.Replace("\t", new string(' ', TabSize));
            base.AppendText(text);
        }

        private void RichTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))
            {
                SuspendLayout();
                int start = SelectionStart;
                string end = Text.Substring(start);
                Text = Text.Substring(0, start);
                Text += (string)Clipboard.GetData("Text") + end;
                SelectionStart = TextLength - end.Length;
                ResumeLayout();
                e.Handled = true;
            }
        }

    } // class
} // namespace
于 2019-10-03T19:35:14.997 回答