【发布时间】:2022-01-20 22:11:20
【问题描述】:
我目前的任务是为一些格式化文本编写一个文本编辑器。出于显而易见的原因,我选择使用 RichTextBox。到目前为止,对于每个键,我都可以修改它的 KeyChar,方法是覆盖 ProcessCmdKey 方法或订阅 KeyPress 事件或覆盖 virtual 方法 OnKeyPress。
我在这个例子中使用的 rtf 文本是这样的:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}{\f1\fnil Courier New;}{\f2\fnil Verdana;}} {\colortbl ;\red0\green0\blue0;} {*\generator Riched20 10.0.19041}\viewkind4\uc1 \pard\sa180\sl72\slmult1\ulc1\ul\b\f0\fs21 Header1:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum。\ulc1\f1\line\ulc1\f0 Lorem ipsum。 \ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\ b\f0 Header2:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1 \f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\b\f0 Header3:\ulc1\ulnone\b0\f1\line \ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1 \line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\line\ulc1\f0 签名...\ulc1\f2\fs20\par }
因此,对于这个 rtf,我基本上是在每次用户按 Enter 时模拟 Shift + Enter,以便在按 Enter 时换行符小于默认换行符。
我为此声明了我自己的RichTextBox,希望我能更深入地挖掘:
public class CustomRichTextBox : RichTextBox { ... }
澄清我到目前为止尝试的方法 - 这些是我的方法,非常适合普通字符:
使用ProcessCmdKey将字符A改为B:
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if(keyData == Keys.A)
{
m.WParam = new IntPtr((int)Keys.B);
return base.ProcessCmdKey(ref m, Keys.B);
}
else if(keyData == (Keys.Shift | Keys.A))
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.B));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.B));
}
return base.ProcessCmdKey(ref m, keyData);
}
使用OnKeyPress将字符A改为B:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == 'A')
{
e.KeyChar = 'B';
}
else if(e.KeyChar == 'a')
{
e.KeyChar = 'b';
}
base.OnKeyPress(e);
}
仅对我按 Enter 键,它不能按预期工作(对我没有影响):
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if (keyData == Keys.Enter)
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.Enter));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.Enter));
}
return base.ProcessCmdKey(ref m, keyData);
}
没有简单的方法来实现这一点还是我错过了什么?
编辑:
我忘记在OnKeyPress 中包含该方法。这是我尝试过的:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == '\r')
{
e.KeyChar = '\u2028';
}
base.OnKeyPress(e);
}
结果如下:
【问题讨论】:
-
你试过在
OnKeyPress()处理它吗?if (e.KeyChar == (char)Keys.Return) ... -
@MatthewWatson 是的,我试过了。我在那里检测到 '\r' 字符。 ('\n' 我在那里找不到)。然后,如果我将其替换为“\u2028”,则行为会变得很奇怪:我有两个,而不是一个正常的换行符。
标签: c# winforms richtextbox