winforms RichTextBox行间距winform C#

xurqigkl  于 2023-03-31  发布在  C#
关注(0)|答案(1)|浏览(309)

大家好,我正在查看System.Windows.Forms.RichTextBox中的行间距更改
我参考了thisthis SO文章,并得出结论,我需要使用PARAFORMAT2结构。
我的要求是我需要将行间距设置为半行间距。这意味着我需要使用bLineSpacingRule = 4,然后使用dyLineSpacing = 100(在我的系统中,单行间距看起来像200)
但这样做的文字被砍成两半。我需要的是“空间近半行”,而不失去我的一半行

  • 第一个正方形包含bLineSpacingRule = 4dyLineSpacing = 100
  • 第二个正方形是bLineSpacingRule = 4dyLineSpacing = 200
  • 我需要第三个方块。

我如何实现这一目标?
我的控件声明如下

public partial class MainForm : Form
{
    string[] Cards = { "A", "K", "Q", "J", "T", "9", "8", "7", "6", "5", "4", "3", "2" };
    [DllImport("user32.dll")]
    static extern bool HideCaret(IntPtr hWnd);

    public class ReadOnlyRichTextBox : RichTextBox
    {
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, Int32 msg,
                                         Int32 wParam, ref PARAFORMAT2 lParam);

        private const int SCF_SELECTION = 1;
        public const int PFM_LINESPACING = 256;
        public const int EM_SETPARAFORMAT = 1095;
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct PARAFORMAT2
        {
            public int cbSize;
            public uint dwMask;
            public Int16 wNumbering;
            public Int16 wReserved;
            public int dxStartIndent;
            public int dxRightIndent;
            public int dxOffset;
            public Int16 wAlignment;
            public Int16 cTabCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public int[] rgxTabs;
            public int dySpaceBefore;
            public int dySpaceAfter;
            public int dyLineSpacing;
            public Int16 sStyle;
            public byte bLineSpacingRule;
            public byte bOutlineLevel;
            public Int16 wShadingWeight;
            public Int16 wShadingStyle;
            public Int16 wNumberingStart;
            public Int16 wNumberingStyle;
            public Int16 wNumberingTab;
            public Int16 wBorderSpace;
            public Int16 wBorderWidth;
            public Int16 wBorders;
        }

        public void SetSelectionLineSpacing(byte bLineSpacingRule, int dyLineSpacing)
        {
            PARAFORMAT2 format = new PARAFORMAT2();
            format.cbSize = Marshal.SizeOf(format);
            format.dwMask = PFM_LINESPACING;
            format.dyLineSpacing = dyLineSpacing;
            format.bLineSpacingRule = bLineSpacingRule;
            SendMessage(this.Handle, EM_SETPARAFORMAT, SCF_SELECTION, ref format);
        }
        [DllImport("user32.dll")]
        static extern bool HideCaret(IntPtr hWnd);
        const int WM_SETFOCUS = 0x0007;
        const int WM_KILLFOCUS = 0x0008;
        [DefaultValue(false)]
        public bool SelectionHighlightEnabled { get; set; }
        public ReadOnlyRichTextBox()
        {
            ReadOnly = true;
            BorderStyle = BorderStyle.None;
            ContextMenu = null;
            BackColor = Color.White;
            GotFocus += TextBoxGotFocus;
            Cursor = Cursors.Arrow; // mouse cursor like in other controls
            SelectionHighlightEnabled = false;
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SETFOCUS && !SelectionHighlightEnabled)
                m.Msg = WM_KILLFOCUS;

            base.WndProc(ref m);
        }

        private void TextBoxGotFocus(object sender, EventArgs args)
        {
            HideCaret(this.Handle);
        }
    }
    private ReadOnlyRichTextBox[] r = new ReadOnlyRichTextBox[169];
    public MainForm()
    {
        int x = 0;
        int y = 0;
        //InitializeComponent();
        //splitContainer1.TabStop = false;
        //RichTextBox rr = new RichTextBox();

        for (int i = 0; i < 169; i++)
        {
            r[i] = new ReadOnlyRichTextBox();
            r[i].SetSelectionLineSpacing(4,200); // This function is called to set line spacing
            //tabControl2.TabPages["Range"].Controls.Add(r[i]);
            this.Controls.Add(r[i]);
            r[i].Size = new Size(40, 40);
            r[i].Location = new Point(x, y);

            if (i % 13 == 12)
            {
                x = 0;
                y += 40;
            }
            else
            {
                x += 40;
            }
            int a = i / 13;
            int b = i % 13;
            string temp = ((a < b) ? (Cards[a] + Cards[b]) : (Cards[b] + Cards[a]));
            r[i].Text += temp + ((a < b) ? "s" : ((a > b) ? "o" : " "));
            if (a == b)
                r[i].BackColor = Color.FromArgb(128 + 5 * a, 128 + 5 * a, 255);
            else if (a < b)
                r[i].BackColor = Color.FromArgb(128 + 5 * a, 255, 128 + 5 * a);
            else if (a > b)
                r[i].BackColor = Color.FromArgb(255, 128 + 5 * a, 128 + 5 * a);

            r[i].Text = r[i].Text + "\n\r" + a.ToString() + b.ToString();
            r[i].SelectionStart = 0;
            r[i].SelectionLength = 3;
            r[i].SelectionFont = new Font(r[i].Font.FontFamily, (float)8.0);
            r[i].SelectionStart = 3;
            r[i].SelectionLength = r[i].TextLength - 3;

            r[i].SelectionFont = new Font(r[i].Font.FontFamily, (float)7.2);
        }
    }        
    private void TextBoxGotFocus(object sender, EventArgs args)
    {
        HideCaret(Handle);
    }
}

我只能使用System.Windows.Forms.RichTextBox,不能使用System.Windows.Controls.RichTextBox,因为这不是WPF应用程序。

ddrv8njm

ddrv8njm1#

不要使用\r\n或WriteLine,请尝试使用SelectionIndent属性,这样可以正常工作!

rtb = new RichTextBox();
rtb.Multiline = true;

rtb.AppendText("Line1" + Environment.NewLine);
rtb.SelectionIndent = 36;
rtb.AppendText(new string('Line2', 250));
rtb.AppendText(Environment.NewLine);
rtb.SelectionIndent = 0;
rtb.AppendText("Line3");

相关问题