.net 修改 RichTextBox 中的默认标签大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/154204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Modifying default tab size in RichTextBox
提问by Adam Haile
Is there any way to change the default tab size in a .NET RichTextBox? It currently seems to be set to the equivalent of 8 spaces which is kinda large for my taste.
有没有办法更改 .NET RichTextBox 中的默认选项卡大小?它目前似乎设置为相当于 8 个空格,这对我来说有点大。
Edit: To clarify, I want to set the global default of "\t" displays as 4 spaces for the control. From what I can understand, the SelectionTabs property requires you to select all the text first and then the the tab widths via the array. I will do this if I have to, but I would rather just change the global default once, if possible, sot that I don't have to do that every time.
编辑:为了澄清,我想将 "\t" 显示的全局默认设置为控件的 4 个空格。据我所知,SelectionTabs 属性要求您首先选择所有文本,然后通过数组选择选项卡宽度。如果必须,我会这样做,但如果可能的话,我宁愿只更改一次全局默认值,这样我就不必每次都这样做。
回答by Scott Nichols
You can set it by setting the SelectionTabsproperty.
您可以通过设置SelectionTabs属性来设置它。
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };
}
UPDATE:
The sequence matters....
更新:
顺序很重要....
If you set the tabs prior to the control's text being initialized, then you don't have to select the text prior to setting the tabs.
如果在初始化控件文本之前设置选项卡,则不必在设置选项卡之前选择文本。
For example, in the above code, this will keep the text with the original 8 spaces tab stops:
例如,在上面的代码中,这将保留带有原始 8 个空格制表位的文本:
richTextBox1.Text = "\t1\t2\t3\t4";
richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };
But this will use the new ones:
但这将使用新的:
richTextBox1.SelectionTabs = new int[] { 100, 200, 300, 400 };
richTextBox1.Text = "\t1\t2\t3\t4";
回答by Dan W
Winforms doesn't have a property to set the default tab size of a RichTexBox with a single number, but if you're prepared to dig into the Rtf of the rich text box, and modify that, there's a setting you can use called: "\deftab". The number afterwards indicates the number of twips (1 point = 1/72 inch = 20 twips). The resulting Rtf with the standard tab size of 720 twips could look something like:
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
}
If you need to convert twips into pixels, use this code inspired from Convert Pixels to Points:
如果您需要将缇转换为像素,请使用受Convert Pixels to Points启发的代码:
int tabSize=720;
Graphics g = this.CreateGraphics();
int pixels = (int)Math.Round(((double)tabSize) / 1440.0 * g.DpiX);
g.Dispose();
回答by Kir_Antipov
It's strange that no one has proposed this method for all this time)
很奇怪,一直没人提出这个方法)
We can inherit from the RichTextBoxand rewrite the CmdKey handler (ProcessCmdKey)
It will look like this:
我们可以继承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);
}
}
Now, when you'll press Tab, a specified number of spaces will be inserted into the control area instead of \t
现在,当您按下 时Tab,将在控制区域中插入指定数量的空格而不是\t
回答by Elmue
If you have a RTF box that is only used to display (read only) fixed pitch text, the easiest thing would be not to mess around with Tab stops. Simply replace them stuff with spaces.
如果您有一个仅用于显示(只读)固定间距文本的 RTF 框,最简单的方法就是不要乱用 Tab 挡位。只需用空格替换它们即可。
If you want that the user can enter something and use that Tab key to advance you could also capture the Tab key by overriding OnKeyDown()and print spaces instead.
如果您希望用户可以输入内容并使用 Tab 键前进,您还可以通过覆盖OnKeyDown()和打印空格来捕获 Tab 键。
回答by s?un????q?p
I'm using this class with monospaced fonts; it replaces all TABs with spaces.
我将这个类与等宽字体一起使用;它用空格替换所有制表符。
All you have to do is to set the following designer properties according to your requirements:
您所要做的就是根据您的要求设置以下设计器属性:
- AcceptsTab = True TabSize
- ConvertTabToSpaces = True
- TabSize = 4
- AcceptsTab = True TabSize
- ConvertTabToSpaces = True
- 标签大小 = 4
Code
代码
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

