Click here to Skip to main content
15,867,835 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a RichTextBox that I am trying to manage the number of characters
in a line when I press the backspace key while entering data.
Because I am using rtbInfo_TextChanged to manage the number of Lines
and the TextLength.
Here are the property settings for the rtbInfo.
No Scroll Bars
Size 347 by 120
Word Wrap is False
Font 10.8. Bold
Mac Length 135

The issue is if you enter text on a line say 10 character and press backspace key
it DECREASES the variable (res) that keeps track of how many character you can enter on a line.
Line of code that needs to be reversed when backspace is pressed res = 33 - cT
I thought about a Function that gets called when backspace is pressed ?
Because I am very new to C# NOT sure how to write this type of Function/Method.
Nor how to make this concept work for my desired goal.
Also very confused how this block of code works protected override bool ProcessCmdKey
YES I copied it from an example it seems to behave as a listener.
Comments Welcomed but not necessary I will research and read further about ProcessCmdKey.
I have commented out some of the code fixes I have tried.
GOAL increase the cT variable when the backspace key press repeatable times.

What I have tried:

public partial class frmRTB : Form
{
    int Count = 0;
    int Lines = 0;
    int cT = 0;
    int total = 0;
    int res;
    int TF;

    public frmRTB()
    {
        InitializeComponent();
    }

    private void frmRTB_Load(Object sender, EventArgs e)
    {
        ActiveControl = rtbInfo;
    }

    public void rtbInfo_TextChanged(Object sender, EventArgs e)
    {
        Count = rtbInfo.TextLength;
        Lines = rtbInfo.Lines.Length;
        //cT = cT + 1;

        txtBoxMsg.Text = "Total of " + (135 - Count) + " can be entered & " + (5 - Lines) + " Lines";

        if (rtbInfo.Text.EndsWith("\n"))
        {
            cT = 0;
        }

        /*====> capture backspace key here <====*/
        //if (TF == 1)
        //{
            cT = cT + 1;
            res = 33 - cT;

            tbMessage.Text = "Total of 1 " + res.ToString() + " more char can be entered on line " + Lines;
            tbCount.Text = "forward C-cT " + cT  + " R " + res;

            total = cT;
        if (total == 33)
            {
                SendKeys.Send("{ENTER}");
                rtbInfo.ScrollToCaret();
                rtbInfo.Focus();
                total = 0;
                cT = 0;
                res = 0;
            }

        //}

        /*if (TF == 2)
        {

            //cT = cT + 1;
            //res = 33 - cT;
            SI = Count - rtbInfo.Text.Length;
            res = res + 1;
            tbMessage.Text = "Total of 2 " + res.ToString() + " more char can be entered on line " + Lines;

            tbCount.Text = "back cT " + cT + " SI " + SI + " R " + res;
           if(Count == 135 | Lines == 0)
            {

                TF = 1;
                tbCount.Text = "It is 1";
                res = 33 - 1;
            }
        }*/

        if (Count == 135)
        {
            rtbInfo.ReadOnly = true;
            //txtBoxMsg.Text = "UP Arrow Key to Edit NOTES";
            tbMessage.Text = "Press Delete Key to Edit NOTES";

        }
        if (Lines == 5)
        {
            rtbInfo.ReadOnly = true;
            //txtBoxMsg.Text = "Only 4 Lines UP Arrow Key to Edit";
            tbMessage.Text = "Only 4 Lines Delete Key to Edit";
        }
        if (rtbInfo.ReadOnly == true)
        {
            tbCount.Visible = true;
            tbCount.Text = "Use BACKSPACE Key to Edit Notes";
        }
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        //if (keyData == Keys.Back | keyData == Keys.Back)
        //{

        if (keyData == Keys.Delete)
            {
                rtbInfo.ReadOnly = false;
                SendKeys.Send("{BACKSPACE}");
                rtbInfo.ScrollToCaret();
                rtbInfo.Focus();
                cT = 0;
                Count = 0;
                Lines = 0;

                return true;
            }

        /*if(keyData == Keys.Back)
        {
            //res = res + 1;
            //SendKeys.Send(" ");
            //rtbInfo.Text.Replace(" ", "");

            //rtbInfo.SelectionStart = rtbInfo.TextLength;
            //rtbInfo.Select(rtbInfo.Text.Length - 0, 0);
            //rtbInfo.AppendText("");
            //rtbInfo.ScrollToCaret();
            //rtbInfo.Focus();
            //rtbInfo.Select(rtbInfo.Text.Length, -1);

            tbMessage.Text = "Total of 2 " + res.ToString() + " more char can be entered on line " + Lines;

            tbCount.Text = "back cT " + cT  + " R " + res;


            //TF = 2;

            return true;
        }*/

        //}

        return base.IsInputKey(keyData);
    }
Posted
Updated 20-Feb-23 9:40am
Comments
[no name] 3-Feb-23 13:01pm    
With 4 lines of 135 characters, you're better off with 4 text boxes. Merge them "later".
Choroid 3-Feb-23 18:38pm    
Gerry I tend to agree that might make it easier
just determined to put the concept in two if
statements one to count up and one to count down
when adding text and deleting text
I am close just too much of a mess to post updated code today
Thanks for the response
[no name] 3-Feb-23 22:37pm    
If you go with the multiple textbox approach, MaxLength "might" help (on data entry).

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.richtextbox.maxlength?view=netframework-4.8

here you go, a solution using the control's own properties:
C#
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void richTextBox1_TextChanged(object sender, EventArgs e)
    {
        labTotalCharacters.Text = richTextBox1.Text.Length.ToString();
            
        labTotalWords.Text = richTextBox1.Text
            .Split(new[]
                {
                    ' ', '\n','?', '!', '.',
                    ':', ';', ',', ')', '(',
                    '[', ']', '{', '}'
                }, 
                StringSplitOptions.RemoveEmptyEntries).Length
            .ToString();

        labTotalLines.Text = richTextBox1.Lines.Length.ToString();
    }

    // bold selected text
    private void button2_Click(object sender, EventArgs e)
    {
        // Remember the selection
        int selstart = richTextBox1.SelectionStart;
        int sellength = richTextBox1.SelectionLength;

        // Set font of selected text
        // You can use FontStyle.Bold | FontStyle.Italic to apply more than
        //    one style
        richTextBox1.SelectionFont
            = new Font(richTextBox1.Font, FontStyle.Bold);

        // Set cursor after the selected text
        richTextBox1.SelectionStart = richTextBox1.SelectionStart +
                                      richTextBox1.SelectionLength;
        richTextBox1.SelectionLength = 0;

        // Set font immediately after selection
        richTextBox1.SelectionFont = richTextBox1.Font;

        // Reselect previous text
        richTextBox1.Select(selstart, sellength);
    }
}

I've added some extra counters plus a formatting test to show rich formatting does not affect the counts and deleting works as expected.

My Test Text (with bold selected text) is:
I have a RichTextBox that I am trying to manage the number of characters
in a line when I press the backspace key while entering data.
Because I am using rtbInfo_TextChanged to manage the number of Lines
and the TextLength.
Here are the property settings for the rtbInfo.
No Scroll Bars
Size 347 by 120
Word Wrap is False
Font 10.8. Bold
Mac Length 135

Total Text Characters: 352
Total words: 66
Total Lines: 10
 
Share this answer
 
Comments
Choroid 20-Feb-23 15:51pm    
Graeme_Grant First Thanks for the Help. It took me a while to understand your code in the Split
I could not get the code in button2 to fire no idea. YES I need to learn how to test code with
the tools that Visual Studio 2019 has. As for my unorthodox naming sorry it is a bad habit from
my days with a Apple /// every bit was precious.The double counting of variables was a mistake
of putting things in InitializeComponent that should NOT have been added there see My Solution
BillWoodruff 2-Mar-23 8:36am    
My apologies for a recent comment ... it has been removed. cheers, Bill
Choroid 2-Mar-23 12:03pm    
Bill I guess I am the OP and as for OP's response to your solution, they may remain confused and "needy." Graeme_Grant solution helped me a great deal as for "needy" In regards to this question the OP spent the better part of a week 6 hours a day trying to solve the issues before posting so if that qualify s as "needy" so be it YES point systems suck and offer little benefit Guess I could just hang on SO The response was deleted that is nice it still shows up in my IN BOX
Graeme_Grant 2-Mar-23 16:16pm    
Not about the points, I could see that you were struggling, hence my post. But at the same time, I do agree with Bill about some that are on here.
This solution is using both TextChange & KeyPress events It includes commented out
code I used for testing. Because I could not effectively capture the Backspace Key
in TextChange I used both events. Suggestion It is more efficient to put all this
code in the KeyPress event only.

namespace ATCTest
{
    public partial class frmCPT : Form
    {
        int rtbTotLen;
        int linesTot;
        int lineNum;
        int res1; 
        int count1;
        int res2;
        int count2;
        int res3;
        int count3;
        int res4;
        int count4;
        int retTot;
        public frmCPT()
        {
            InitializeComponent();
            //rtbInfo.TextChanged += rtbInfo_TextChanged;
            //rtbInfo.KeyPress += rtbInfo_KeyPress;
            // Do NOT use this code HERE look when to use code here
        }
        private void rtbInfo_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Escape)
            {
                rtbInfo.Select(0, 0);
            }

           if (e.KeyChar == (char)Keys.Back)
            {
                if (lineNum == 1)
                {
                    --res1;
                }
                if (lineNum == 2)
                {
                    --res2;
                }
                if (lineNum == 3)
                {
                    --res3;
                }
                if (lineNum == 4)
                {
                    --res4;
                }
            }
            else
            {
                if (lineNum == 1)
                {
                    ++res1;
                }
                if (lineNum == 2)
                {
                    ++res2;
                }
                if (lineNum == 3)
                {
                    ++res3;
                }
                if (lineNum == 4)
                {
                    ++res4;
                }
            }
        }
        private void rtbInfo_TextChanged(object sender, EventArgs e)
        {
            rtbTotLen = rtbInfo.TextLength;
            linesTot = rtbInfo.Lines.Length;
            lineNum = (5 - linesTot);
           
            txtBoxMsg.Text = "Total of " + (135 - rtbTotLen) + " can be entered on " + (5 - lineNum) + " Lines";
          
            /*tbMessage.Text = rtbInfo.Text
                .Split(new[]
                    {
                    ' ', '\n','?', '!', '.',
                    ':', ';', ',', ')', '(',
                    '[', ']', '{', '}'
                    },
                    StringSplitOptions.RemoveEmptyEntries).Length.ToString();*/
            // this code above counts spaces and returns Wild Code 
            /*if (Regex.IsMatch(rtbInfo.Text, @"^[\d \w \s]+$"))
            {  // This code is for testing not needed
            }*/
            // Code below for testing which line I was using
            /*if (rtbInfo.Text.EndsWith("\n") & lineNum ==4)
            {
                ++retTot;
                tbTest.Text = "Found 4 " + retTot + " in line" + lineNum + "";
             }
             else if (rtbInfo.Text.EndsWith("\n") & lineNum == 3)
             {
                 ++retTot;
                 tbTest.Text = "Found 3 " + retTot + " in line" + lineNum + "";
             }
             else if (rtbInfo.Text.EndsWith("\n") & lineNum == 2)
             {
                 ++retTot;
                 tbTest.Text = "Found 2 " + retTot + " in line " + lineNum + "";
             }
             else if (rtbInfo.Text.EndsWith("\n")& lineNum == 1)
             {
                 ++retTot;
                 tbTest.Text = "Found 1 " + retTot + " in line " + lineNum + "";
             }else if (rtbInfo.Text.EndsWith("\n"))
            {
                ++retTot;
                tbTest.Text = "Found 0 " + retTot + " in line " + lineNum + "";
            }*/

            if (lineNum == 4)
             {
                count4 = 33 - res4;
                tbMessage.Text = "Total of " + count4 + " more char can be entered on line " + (5 - lineNum) + "";
                if (count4 == 0)
                {
                    SendKeys.Send("{ENTER}");
                    //rtbInfo.AppendText("\n");
                    // SendKeys sent the cursor down two places with TextChanged set in  InitializeComponent
                    // So I used the AppendText method This and variables counting twice What is Going Wrong !
                    rtbInfo.ScrollToCaret();
                    rtbInfo.Focus();
                 }
             }
            else if (lineNum == 3)
            {
                count3 = 33 - res3;
                tbMessage.Text = "Total of " + count3 + " more char can be entered on line " + (5 - lineNum) + "";
                if (count3 == 0)
                {
                    rtbInfo.AppendText("\n");
                    rtbInfo.ScrollToCaret();
                    rtbInfo.Focus();
                }
            }
            else if (lineNum == 2)
            {
                count2 = 33 - res2;
                tbMessage.Text = "Total of " + count2 + " more char can be entered on line " + (5 - lineNum) + "";
                if (count2 == 0)
                {
                    rtbInfo.AppendText("\n");
                    rtbInfo.ScrollToCaret();
                    rtbInfo.Focus();
                }
            }
            else if (lineNum == 1)
            {
                count1 = 33 - res1;
                tbMessage.Text = "Total of " + count1 + " more char can be entered on line " + (5 - lineNum) + "";
                if (count1 == 0)
                {
                    rtbInfo.AppendText("\n");
                    rtbInfo.ScrollToCaret();
                    rtbInfo.Focus();
                }
            }
            if (linesTot == 5 | rtbTotLen == 135)
            {
                rtbInfo.ReadOnly = true;
            }

            if (rtbInfo.ReadOnly == true)
            {
                txtBoxMsg.Text = "";
                tbMessage.Text = "";
                tbCount.Text = "Use BACKSPACE Key to Edit";
            }

            if (rtbInfo.ReadOnly == true)
            {
                txtBoxMsg.Text = "";
                tbMessage.Text = "";
                tbCount.Text = "Use BACKSPACE Key to Edit";

                string message = "Press YES to edit Notes" + '\n' + "        NO Clear Notes";
                string title = "Edit Notes";
                MessageBoxButtons buttons = MessageBoxButtons.YesNo;
                DialogResult result = MessageBox.Show(message, title, buttons);
                if (result == DialogResult.Yes)
                {
                    rtbInfo.ReadOnly = false;
                    SendKeys.Send("{BACKSPACE}");
                    rtbInfo.ScrollToCaret();
                    rtbInfo.Focus();
                }
                else
                {
                    rtbInfo.ReadOnly = false;
                    rtbInfo.Clear();
                    tbCount.Text = "All Notes Remove";
                }
            }
        }

        private void btnToStart_Click(object sender, EventArgs e)
        {
            Close();
            frmStart fS = new frmStart();
            fS.Show();
        }

        private void frmCPT_Load(object sender, EventArgs e)
        {
            ActiveControl = rtbInfo;
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900