Question How do I update a specific line of text in richtextbox and then sort it every time spacebar is pressed?

Wowywow

Member
Joined
Nov 9, 2019
Messages
16
Programming Experience
Beginner
So this was part of another exercise and professor just randomly came up with this extra part just for me ( others got different ones, and much easier ones... ). What I need to do is when he enters extra numbers into the last line of richtextbox ( where the numbers sorted in descending order are ) and then whenever I press "Spacebar" those numbers should be sorted. EX: 20 14 12 2 ( I type in: 14 ), So the last lines changes to "20 14 14 12 2" and so on. I made the "Spacebar press event", but the problem is how do I update the last line of text and add the numbers he types into the string ( I already failed the assignment, because I couldn't make the program during the class. So this is purely for self education ).
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string descendingNums = string.Empty;

        // private kint. struct
        struct trecDalis
        {
            private string line2;
            private string line3;
            private string line4;

            public void priskLine(string aLine2, string aLine3, string aLine4)
            {
                line2 = aLine2;
                line3 = aLine3;
                line4 = aLine4;
            }

            public void print(RichTextBox rch)
            {
                rch.Text += '\n' + line2 +
                    '\n' + line3 +
                    '\n' + line4 + '\n';
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string file = System.IO.Directory.GetCurrentDirectory() + @"\duom.txt";
            string data;
            if (File.Exists(file))
            {
                label1.Text = "Failas yra";
                data = File.ReadAllText(file);
                string[] lines = data.Split('\n');

                // skaiciai didejimo tvarka
                int[] ascending = lines[0].Split(' ').Select(int.Parse).ToArray();
                Array.Sort(ascending);
                richTextBox1.Text += "---Skaičiai didėjimo tvarka---" + '\n';
                for (int i = 0; i < ascending.Length; i++)
                {
                    richTextBox1.Text += Convert.ToString(ascending[i]) + " ";
                }
                //--------------------------------

                // priskiriama struct
                trecDalis uzd = new trecDalis();
                uzd.priskLine(lines[1], lines[2],lines[3]);
                richTextBox1.Text += '\n' + "---Private kintamieji struct---";
                uzd.print(richTextBox1);
                //--------------------------------

                // balsiai
                string str = lines[4] + lines[5] + lines[6];
                int bA = 0, bE = 0, bI = 0, bO = 0, bU = 0;
                char[] arr = str.ToArray();
                for (int i = 0; i < str.Length; i++)
                {
                    if (arr[i] == 'a')
                    {
                        bA++;
                    }
                    else if (arr[i] == 'e')
                    {
                        bE++;
                    }
                    else if (arr[i] == 'i')
                    {
                        bI++;
                    }
                    else if (arr[i] == 'o')
                    {
                        bO++;
                    }
                    else if (arr[i] == 'u')
                    {
                        bU++;
                    }
                }
                richTextBox1.Text += "---Balsiai---" + '\n';
                richTextBox1.Text += "A=" + Convert.ToString(bA) + '\n';
                richTextBox1.Text += "E=" + Convert.ToString(bE) + '\n';
                richTextBox1.Text += "I=" + Convert.ToString(bI) + '\n';
                richTextBox1.Text += "O=" + Convert.ToString(bO) + '\n';
                richTextBox1.Text += "U=" + Convert.ToString(bU);
                // --------------------------------------------

                // skaiciai maziejimo tvarka

                string numDesc = lines[7] + lines[8] + lines[9];
                int[] descending = numDesc.Split(' ', '\n', '\r').Select(int.Parse).ToArray();
                Array.Sort(descending);
                Array.Reverse(descending);
                richTextBox1.Text += '\n';
                richTextBox1.Text += "---Skaičiai mažėjimo tvarka---" + '\n';
                for (int i = 0; i < descending.Length; i++)
                {
                    richTextBox1.Text += Convert.ToString(descending[i]) + " ";
                }


                descendingNums = string.Join("", descending);

            }
            else
            {
                label1.Text = "Failo nėra";
            }
        }

        private void Space_Pressed(object sender, KeyPressEventArgs e)
        {
            if(e.KeyChar == (char)Keys.Space)
            {
                string[] lines = richTextBox1.Lines;
                lines[13] = richTextBox1.Text;
                richTextBox1.Lines = lines;
                richTextBox1.Text += descendingNums;
            }
        }
    }
}

The problem is when I try to update the last line it just copies everything... is it possible to even do this with the way I set this up?

This is how the form looks like:
Capture.PNG


The data should be included.
 

Attachments

  • duom.txt
    354 bytes · Views: 10

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,175
Location
Chesapeake, VA
Programming Experience
10+
Looks like fun:
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SimpleCSWinForms
{
    class Program : Form
    {
        Program()
        {
            var rtb = new RichTextBox()
            {
                Dock = DockStyle.Fill
            };

            rtb.KeyUp += (o, e) =>
            {
                if (e.KeyCode == Keys.Space)
                {
                    var lines = rtb.Lines;
                    var lastLine = lines.Length - 1;
                    lines[lastLine] = lines[lastLine]
                                        .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                                        .Select(s => Int32.TryParse(s, out int n) ? n : n)
                                        .OrderByDescending(n => n)
                                        .Aggregate("", (acc, n) => acc += n + ' ');
                    rtb.Lines = lines;
                    rtb.Select(rtb.TextLength, 0);
                }
            };

            Controls.Add(rtb);
        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Program());
        }
    }
}

Of course, the code above is even more complex because it now includes the use of LINQ to:
  1. Parse the last line into space delimited tokens.
  2. Parse each token into an integer.
  3. Sort the integers into descending order.
  4. Rebuild a string with the numbers followed by spaces.
Chances are that the instructor will once again just fail the student if they just copied and pasted the code above without explanations.

I recommend using the method suggested by @Sheepings above which is to do things step by step using the classes and methods he mentioned.
 

Wowywow

Member
Joined
Nov 9, 2019
Messages
16
Programming Experience
Beginner
Chances are that the instructor will once again just fail the student if they just copied and pasted the code above without explanations.
Not that it matters, I already failed the assignment ( as I had to deliver it 2 hours after he gave it to me )
 

Sheepings

Well-known member
Joined
Sep 5, 2018
Messages
2,076
Programming Experience
10+
Providing I gave you the documentation, which provides sample code for example purposes, including descriptive information on how to use it. Or did you think I gave those links just for fun? Hmm
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,175
Location
Chesapeake, VA
Programming Experience
10+
With the RichTextBox to append text you simply append to the Text property like you were doing in your original post. What do you think you were doing in all your lines of code where you had richTextBox.Text += ...?

The more interesting problem is how to replace existing text. The standard approach is to set the selection using the Select() method to select the text that you wish to replace, and then set the SelectedText property with the new text you want to display.

The non-standard approach is to completely replace the Text or Lines properties with the new values you want to display. That's the approach I took in my code in post #3. I copied the existing lines on line #22. I figured out the last line on line #23. On lines 24-28, I replaced the text for the last line with the sorted numbers. Then finally on line #29, I replace the lines that are in the RichTextBox.
 

Wowywow

Member
Joined
Nov 9, 2019
Messages
16
Programming Experience
Beginner
Providing I gave you the documentation, which provides sample code for example purposes, including descriptive information on how to use it. Or did you think I gave those links just for fun? Hmm
C#:
        private void Space_Pressed(object sender, KeyPressEventArgs e)
        {
            if(e.KeyChar == (char)Keys.Space)
            {
                string newNums;
                newRTB = richTextBox1.Text;
                List<string> diff;
                IEnumerable<string> oldStr = oldRTB.Split(' ', '\n').Distinct();
                IEnumerable<string> newStr = newRTB.Split(' ', '\n').Distinct();
                diff = newStr.Except(oldStr).ToList();
                foreach(object o in diff)
                {
                    sb.Append(" " + o);
                    oldRTB = sb2.Append(" " + o).ToString();
                }
                diff.Clear();

                string[] lines = richTextBox1.Lines;
                lines[13] = string.Empty;
                richTextBox1.Lines = lines;

                newNums = sb.ToString();
                int[] descending2 = newNums.Split(' ').Select(int.Parse).ToArray();
                Array.Sort(descending2);
                Array.Reverse(descending2);
                for (int i = 0; i < descending2.Length; i++)
                {
                    richTextBox1.Text += Convert.ToString(descending2[i]) + " ";
                }


            }
        }
Well I did this... it feels wrong for some reason. It works, but for some reason, when I type "100" that number gets completely ignored and doesn't get printed, but "101" and so on does... any ideas?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,175
Location
Chesapeake, VA
Programming Experience
10+
You are overcomplicating things. Why do you need new and old RichTextBoxes?
 

Sheepings

Well-known member
Joined
Sep 5, 2018
Messages
2,076
Programming Experience
10+
But you don't need to do that. You just need to do it as I first outlined. You're over complicating it, and you shouldn't be using the RTB for anything until you have finished updating the way the text is meant to be outputted to the RTB. You may as well bin the StringBuilder if you aren't going to use it efficiently.
 

Wowywow

Member
Joined
Nov 9, 2019
Messages
16
Programming Experience
Beginner
But you don't need to do that. You just need to do it as I first outlined. You're over complicating it, and you shouldn't be using the RTB for anything until you have finished updating the way the text is meant to be outputted to the RTB. You may as well bin the StringBuilder if you aren't going to use it efficiently.
Well I don't really know how to use StringBuilder, as I never used it before and especially in this case
 

Sheepings

Well-known member
Joined
Sep 5, 2018
Messages
2,076
Programming Experience
10+
You won't learn if you don't research and read :
You've over-complicated it. Use StringBuilder and stringbuilder append. .split, and .substring.

Build the structure with properties or variables before sending the text to the RTB.
Are you honestly trying to tell me that you have read the documentation and are still completely clueless, or did you just type StringBuilder into the IDE and let Intellisense help you some of the way?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,175
Location
Chesapeake, VA
Programming Experience
10+
I'am comparing current RTB ( oldRTB ) with new (whatever they enter ) then take the new value and append it too the string.
But there is no need to compare the previous text with the new text.

The assignment description above says that it is only the last line that needs to be sorted when the space bar is pressed. So that means that you can always take the last line, read the numbers found there, sort the numbers, and then replace the last line. There is no need to try to do an insertion sort by trying to figure out what new number got typed into the last line, and then trying to insert that number into a sorted array. Just take everything in and re sort all the numbers.
 
Top Bottom