views:

229

answers:

4

I'm wondering what event/events is/are being used in counting the vowels while you're typing the sentence in the textbox.

I'm not quite sure if it's something to do with "KeyPress" or "KeyUp".

I would appreciate your help.

=====

This is now where I'm stucked:

  private void textBox1_TextChanged(object sender, EventArgs e)
    {
        string yourSentence;
        yourSentence = textBox1.Text.ToLower().Trim();

        char ch1 = 'a';
        char ch2 = 'e';
        char ch3 = 'i';
        char ch4 = 'o';
        char ch5 = 'u';

        int counta = 0;
        int counte = 0;
        int counti = 0;
        int counto = 0;
        int countu = 0;

        int j = counta + counte + counti + counto + countu;



 foreach (char v in yourSentence)
 {
     if (v == ch1) { counta++; j++; }

     else if (v == ch2) { counte++; j++; }

     else if (v == ch3) { counti++; j++; }

     else if (v == ch4) { counto++; j++; }

     else if (v == ch5) { countu++; j++; }
 }

       listBox1.Items.Clear();

      listBox1.Items.Add("There are " + counta.ToString().Trim() + " a's in the sentence");
        listBox1.Items.Add("There are " + counte.ToString().Trim() + " e's in the sentence");
        listBox1.Items.Add("There are " + counti.ToString().Trim() + " i's in the sentence");
        listBox1.Items.Add("There are " + counto.ToString().Trim() + " o's in the sentence");
        listBox1.Items.Add("There are " + countu.ToString().Trim() + " u's in the sentence");
        listBox1.Items.Add("All in all there are " + j.ToString().Trim() + " vowels in the sentence");

This is working perfectly. Thanks :-)

+4  A: 

Well there is a TextChanged event in the TextBox that triggers whenever a character is typed or deleted. This could be used to count vowels in real-time.

Edit:

I combined your code from textBox1_keyDown and btnCount_Click and put it in the TextChanged event, and it worked almost perfectly. I only had to add one line:

listBox1.Items.Clear();

...just before items are added to the listbox. This way, the listbox is emptied before adding the counts.

This is the result:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        string yourSentence;
        yourSentence = textBox1.Text.ToLower().Trim();

        char ch1 = 'a';
        char ch2 = 'e';
        char ch3 = 'i';
        char ch4 = 'o';
        char ch5 = 'u';

        int counta = 0;
        int counte = 0;
        int counti = 0;
        int counto = 0;
        int countu = 0;

        int j = counta + counte + counti + counto + countu;



        foreach (char v in yourSentence)
        {
            if (v == ch1) { counta++; j++; }

            else if (v == ch2) { counte++; j++; }

            else if (v == ch3) { counti++; j++; }

            else if (v == ch4) { counto++; j++; }

            else if (v == ch5) { countu++; j++; }
        }


        listBox1.Items.Clear();
        listBox1.Items.Add("There are " + counta.ToString().Trim() + " a's in the sentence");
        listBox1.Items.Add("There are " + counte.ToString().Trim() + " e's in the sentence");
        listBox1.Items.Add("There are " + counti.ToString().Trim() + " i's in the sentence");
        listBox1.Items.Add("There are " + counto.ToString().Trim() + " o's in the sentence");
        listBox1.Items.Add("There are " + countu.ToString().Trim() + " u's in the sentence");
        listBox1.Items.Add("All in all there are " + j.ToString().Trim() + " vowels in the sentence");

    }

I don't need any other code to make this work.

Meta-Knight
@Meta-Knight: i see that means whenevery I type a sentence it will recognize the vowels on it and display the count. Is that correct?
tintincute
Nonono... that just means whatever code you put in the TextChanged event will be called everytime the text is changed. So if you put code which calculates the vowel count and displays it, the vowel count will be updated every time the textbox's content changes.
Meta-Knight
@Meta-Knight: I will try this. Do I have to highlight my textbox and double click on the event TextChanged? Then from there I'll include my code? is that right?Thanks
tintincute
In the Code View you choose the textbox in the controls list (top-left), then choose TextChanged in the events list (top-right). A TextBox_TextChanged method in which you can add your code will be generated.
Meta-Knight
@Meta-Knight: I did it but it seems it repeatedly displays the count. For ex:if I write: "a" it will display like this repeatedly: "There are 0 a's, There are 0 e's, There are 0 i's, There are 0 o's, There are 0 u's". Do I need to add something here aside from my code?
tintincute
Edit your original post and show us your code. Then we can help you.
Meta-Knight
Thanks for posting your code. I edited my post ;)
Meta-Knight
@Meta-Knight: Thanks for checking my code. Does that mean I don't have to add the " private void textBox1_KeyDown(object sender, EventArgs e)" anymore? I'm not sure if I still retain the "btnCount_Click" because as I see it, it looks redundant if it counts twice.
tintincute
You don't need KeyDown, TextChanged is triggered as soon as you add/remove a character in your text. Your count button has no use anymore, too.
Meta-Knight
@Meta-Knight: I'm sorry if I'm having a difficulty to understand. what method shall I use now if I also don't need the count button. Where shall I include all my codes then? In my code I still have the: " private void textBox1_KeyDown(object sender, EventArgs e)" in there which I haven't finished because I'm not sure what to include.
tintincute
@Meta-Knight: thanks I think I see what you mean...I'll edit my code so that I can also show it to you. and it works fine:-) that means I don't need any event from here
tintincute
OK, I edited my post anyway to be more clear ;-)
Meta-Knight
@Meta-Knight: Thanks for the input and idea. I also have the same result as yours:-)see my edited post above:-)this works fine now. Thanks again.Cheers
tintincute
A: 

Keypress is fired when the key is pressed. (not sure about it) key UP is fired when the Key rises up (released) (remove ur finger off the keyboard)

Ahmad Farid
@Ahmad Farid: thank you for the definition.Do you know what event to use to count a letter while typing?Thanks
tintincute
And there is KeyDown. KeyDown is fired when the key is first pressed, then (possibly several) events KeyPressed are fired, depending on the keyboard repetition rate of the OS. KeyUp fires when the key is released.
Ralph Rickenbach
tintincute
+1  A: 

Let's see. This can be done in all of these, but some of the events are more likely for it.

KeyDown: In KeyDown, the key still is represented as an integer usually. You would have to map the vowels yourself. Repeated values only fire once. So you might loose some vowels.

KeyPressed: here you get the key in it's right representation. Add one if a vowel is pressed. But do I have to subtract one if del or backspace is pressed? You do not know which key was deleted.

KeyUp: Again, the representation is an integer. Repeated values only fire ones.

TextChanged: This is triggered whenever the text changes. In here you do not know exactly what the last key pressed was (it could be womewhere within the text), so you ve to recount the number of vowels from start.

I would do that somewhat like this:

private void textBox1_TextChanged(object sender, EventArgs e)
 {
      btnCount_Click(sender, e);
 }

This way the calculation is done everytime the text changes, and in addition can be done pressing the button too. If you do not like to call an event function directly, make a function that is called from both places.

And maybe you want to do this only from time to time (see other answers) in TextChanged.

Ralph Rickenbach
tintincute
What is your code, then? To see whether the code is executed, just make a breakpoint on a line of your code. Then, if it does execute, see what your code does.
Ralph Rickenbach
+2  A: 

I built a search box that acts something like an AJAX text box - it does the search basd on what has been typed "so far" in the text box. There's no need to type in the text and then click an associated button. It searches as you type. I don't know if there's a name for this UI pattern, there oughta be.

The dynamic search is hooked to the TextChanged event. But the key was, I didn't it want to search while the text was being actively changed, as the user was typing. I wanted to search when the changes were complete, when the typing stopped.

This may be interesting for you too.

The hueristic I used: if 600ms elapses after the last textchange event, then typing has stopped, and that's when the search should run. But how do you get code to run 600ms AFTER a TextChange event. It's not possible to Thread.Sleep within the event handler. This just causes UI delay.

The solution I came up with was this: use Threadpool.QueueUserWorkItem in the TextChange event to queue up a worker method, called MaybeDoSearch. In that worker, do a Thread.Sleep for the delay interval (600ms). When the Sleep completes, check the elapsed time since the prior TextChanged event. If that time exceeds 600 ms, then actually do the Search.

It looks like this

    System.DateTime _lastChangeInSearchText;
    private const int DELAY_IN_MILLISECONDS = 600;

    private void tbSearch_TextChanged(object sender, EventArgs e)
    {
        _lastChangeInSearchText = System.DateTime.Now;
        string textToFind = tbSearch.Text;
        if ((textToFind != null) && (textToFind != ""))
            System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(MaybeDoSearch), textToFind);
        else 
        {
            // clear the ListView that contains the search results 
            this.ListView2.Items.Clear();
        }
    }

    private void MaybeDoSearch(object o)
    {
        System.Threading.Thread.Sleep(DELAY_IN_MILLISECONDS);
        System.DateTime now = System.DateTime.Now;
        var _delta = now - _lastChangeInSearchText;
        if (_delta >= new System.TimeSpan(0,0,0,0,DELAY_IN_MILLISECONDS))
        {
            // actually do the search
            ShowSearchResults();
        }
    }

Mine is a WinForms app. Because the MaybeDoSearch() runs on a worker thread, not the UI thread, then in the ShowSearchResults(), UI update must be protected with InvokeRequired.

During normal typing, a person will type 2 or 3 characters in 600ms. The result is there are 2 or 3 work items queued and running (mostly Sleeping), on separate threadpool threads, at any given moment while typing is actively occurring.

Someone suggested earlier that you will have to re-scan all of the text for vowels with every change. It's redundant work at runtime, which for efficiency purposes you'd normally want to avoid. But the code is so much simpler that way. I had the same issue, and decided to not try to figure out just how the text changed with the current TextChange event. It changed, so the code does a full new search. The search completes quicker than the delay interval (600ms). In your case, counting vowels, it will be even faster.

Cheeso
@Cheeso: as i'm not yet quite familiar with all of the syntax in c#, the first time I saw your coding it looks difficult but I think you're right. With the: "System.DateTime _lastChangeInSearchText;"Is it declared after the public Form 1:Form or do I need to create a class for that? Thanks for your suggestion.I would love to try this
tintincute
you don't need a new class. _lastChangeInSearchText is just another member variable in your Form class.
Cheeso
@Cheeso: so that would belong to the same class where I add my methods?
tintincute
yes it would. And the tbSearch_TextChanged method is just an event handler, in your Form class, which should be hooked to the TextChanged event of your text box. All in the same class.
Cheeso
tintincute
I don't know what you're talking about. What fixed numbers? 600ms? That's why it's a const int. There have got to be SOME fixed numbers. The position and size of your textbox are fixed, I presume, and represented with numbers. ?? If you want to make the delay modifiable, you could introduce a .config file to hold the value, but that seems like YAGNI. You Aren't Gonna Need It.
Cheeso
oops sorry about that, I mislooked the constant for 600 ms. yes that's what I meant.
tintincute