Как установить ширину TAB в элементе управления Windows Forms TextBox?
Для управления текстовым полем WinForms TextBox с MultiLine = true
и AcceptsTab == true
, как я могу установить ширину отображаемого символа табуляции?
Я хочу использовать это как быстрое и грязное поле ввода script для плагина. Это действительно не обязательно быть фантазией, но было бы неплохо, если вкладки не отображались в виде 8 символов...
Из принятого ответа:
// set tab stops to a width of 4
private const int EM_SETTABSTOPS = 0x00CB;
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);
public static void SetTabWidth(TextBox textbox, int tabWidth)
{
Graphics graphics = textbox.CreateGraphics();
var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width;
SendMessage(textbox.Handle, EM_SETTABSTOPS, 1,
new int[] { tabWidth * characterWidth });
}
Это можно вызвать в конструкторе вашего Form
, но остерегайтесь: убедитесь, что InitializeComponents
запущен первым.
Ответы
Ответ 1
Я думаю, что отправка сообщения EM_SETTABSTOPS
в TextBox будет работать.
// set tab stops to a width of 4
private const int EM_SETTABSTOPS = 0x00CB;
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);
public static void SetTabWidth(TextBox textbox, int tabWidth)
{
Graphics graphics = textbox.CreateGraphics();
var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width;
SendMessage
( textbox.Handle
, EM_SETTABSTOPS
, 1
, new int[] { tabWidth * characterWidth }
);
}
Это можно вызвать в конструкторе вашей Form
, но будьте осторожны: убедитесь, что InitializeComponents
запускается первым.
Ответ 2
Я знаю, что вы используете TextBox
в настоящее время, но если вы можете избежать использования RichTextBox
вместо этого, вы можете использовать свойство SelectedTabs для установки необходимой ширины табуляции:
richTextBox.SelectionTabs = new int[] { 15, 30, 45, 60, 75};
Обратите внимание, что эти смещения являются пикселями, а не символами.
Ответ 3
Предлагаемый пример неверен.
Сообщение EM_SETTABSTOPS
ожидает, что размеры вкладок будут указаны в блоках диалогового шаблона, а не в пикселях. После некоторого копания, похоже, что блок шаблона диалога равен 1/4th средней ширине символа окна. Таким образом, вам нужно указать 8 для 2-х значных букв, 16 для четырех символов и т.д.
Таким образом, код можно упростить как:
public static void SetTabWidth(TextBox textbox, int tabWidth)
{
SendMessage(textbox.Handle, EM_SETTABSTOPS, 1,
new int[] { tabWidth * 4 });
}
Ответ 4
С помощью методов расширения вы можете добавить новый метод в класс управления TextBox. Это моя реализация (включая дополнительный метод расширения, который дает вам координаты для текущего местоположения вставки) из того, что я собрал из предыдущих авторов выше:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Extensions
{
public static class TextBoxExtension
{
private const int EM_SETTABSTOPS = 0x00CB;
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);
public static Point GetCaretPosition(this TextBox textBox)
{
Point point = new Point(0, 0);
if (textBox.Focused)
{
point.X = textBox.SelectionStart - textBox.GetFirstCharIndexOfCurrentLine() + 1;
point.Y = textBox.GetLineFromCharIndex(textBox.SelectionStart) + 1;
}
return point;
}
public static void SetTabStopWidth(this TextBox textbox, int width)
{
SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, new int[] { width * 4 });
}
}
}
Ответ 5
это очень полезно:
Установка позиций табуляции для многострочного элемента управления TextBox
Ответ 6
Для тех, кто хочет разные ширины вкладок, я использовал этот подход:
using System.Runtime.InteropServices;
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam);
private const int EM_SETTABSTOPS = 0x00CB;
private void InitialiseTabStops()
{
// Declare relative tab stops in character widths
var tabs = new uint[] { 2, 2, 4, 8, 2, 32 };
// Convert from character width to 1/4 character width
for (int position = 0; position < tabs.Length; position++)
tabs[position] *= 4;
// Convert from relative to absolute positions
for (int position = 1; position < tabs.Length; position++)
tabs[position] += tabs[position - 1];
SendMessage(textBox.Handle, EM_SETTABSTOPS, tabs.Length, tabs);
}