Изменение размера вкладки по умолчанию в RichTextBox

Можно ли изменить размер закладки по умолчанию в .NET RichTextBox? В настоящее время он, похоже, настроен на эквивалент 8 пространств, которые являются большими по своему вкусу.

Изменить: Чтобы уточнить, я хочу установить глобальное значение по умолчанию для "\ t" как 4 пробела для элемента управления. Из того, что я могу понять, свойство SelectionTabs требует, чтобы вы сначала выделили весь текст, а затем ширину табуляции через массив. Я сделаю это, если потребуется, но я предпочел бы просто изменить глобальное значение по умолчанию, если это возможно, sot, что я не должен делать это каждый раз.

Ответы

Ответ 1

Вы можете установить его, установив свойство SelectionTabs.

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

UPDATE:
Последовательность имеет значение....

Если вы устанавливаете вкладки перед инициализацией текста управления, вам не нужно выбирать текст перед установкой вкладок.

Например, в приведенном выше коде это сохранит текст с исходными 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";

Ответ 2

Winforms не имеет свойства, чтобы установить размер табуляции по умолчанию RichTexBox с одним номером, но если вы готовы копать в Rtf текстового поля rich и изменить его, вы можете установить использование: "\ deftab". Затем число указывает количество твипов (1 точка = 1/72 дюйма = 20 твитов). Полученный Rtf со стандартным размером вклада 720 твинов может выглядеть примерно так:

{\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
}

Если вам нужно преобразовать twips в пиксели, используйте этот код, вдохновленный Конвертировать пиксели в точки:

int tabSize=720;
Graphics g = this.CreateGraphics();
int pixels = (int)Math.Round(((double)tabSize) / 1440.0 * g.DpiX);
g.Dispose();

Ответ 3

Если у вас есть поле RTF, которое используется только для отображения (только для чтения) текста с фиксированным шагом, проще всего было бы не вмешиваться в Tab-стопы. Просто замените их материалом пробелами.

Если вы хотите, чтобы пользователь мог что-то ввести и использовать эту клавишу Tab для продвижения, вы также можете захватить клавишу Tab, переопределив OnKeyDown() и вместо этого напечатайте пробелы.

Ответ 4

Странно, что никто не предлагал этот метод все это время)

Мы можем наследовать от 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 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

Ответ 5

Я использую этот класс с моноширинными шрифтами; он заменяет все табуляции пробелами.

Все, что вам нужно сделать, это установить следующие свойства дизайнера в соответствии с вашими требованиями:

  • AcceptsTab = True TabSize
  • ConvertTabToSpaces = True
  • TabSize = 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