【问题标题】:Events in counting vowels元音计数事件
【发布时间】:2009-07-28 12:04:21
【问题描述】:

我想知道当您在文本框中键入句子时,在计算元音时使用了哪些事件/事件。

我不太确定这是否与“KeyPress”或“KeyUp”有关。

感谢您的帮助。

=====

这就是我现在卡住的地方:

  private void btnCount_Click(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.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");


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

         //I think I have to add the codings here. But what will happened to the 
         //btnCount_Click?

     }

【问题讨论】:

  • 您是在尝试自己执行此操作,还是在谈论执行此操作的特定应用程序?
  • 我正在尝试自己做。我使用 switch 语句编写了一个代码,它计算元音并在列表框中显示元音的数量。现在我想尝试一些新的东西,比如如果我写句子它会识别元音并显示有多少元音在写作。
  • 注意,因为有人可以选择大部分文本并覆盖它。
  • 您好,请检查我对 cme​​ts 的编辑,了解您的代码!

标签: c# counter


【解决方案1】:

好吧,TextBox 中有一个TextChanged 事件,只要输入或删除字符就会触发。这可用于实时计算元音。

编辑:

我将 textBox1_keyDown 和 btnCount_Click 中的代码组合在一起,并将其放入 TextChanged 事件中,它几乎可以完美运行。我只需要添加一行:

listBox1.Items.Clear();

...就在项目被添加到列表框之前。这样,列表框会在添加计数之前清空。

这是结果:

    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");

    }

我不需要任何其他代码来完成这项工作。

【讨论】:

  • @Meta-Knight:我明白这意味着每当我输入一个句子时,它都会识别出上面的元音并显示计数。对吗?
  • Nonono... 这只是意味着您在 TextChanged 事件中放置的任何代码都会在每次更改文本时被调用。因此,如果您输入计算元音计数并显示它的代码,则每次文本框内容更改时都会更新元音计数。
  • @Meta-Knight:我会试试这个。我是否必须突出显示我的文本框并双击事件 TextChanged?然后从那里我将包括我的代码?是吗?谢谢
  • 在代码视图中选择控件列表中的文本框(左上角),然后在事件列表中选择 TextChanged(右上角)。将生成一个 TextBox_TextChanged 方法,您可以在其中添加代码。
  • @Meta-Knight:我做到了,但它似乎反复显示计数。例如:如果我写:“a”,它将重复显示:“有 0 个 a,有 0 个 e,有 0 个 i,有 0 个 o,有 0 个 u”。除了我的代码,我还需要在这里添加一些东西吗?
【解决方案2】:

我构建了一个类似于 AJAX 文本框的搜索框 - 它根据在文本框中输入的“到目前为止”的内容进行搜索。无需输入文本,然后单击相关按钮。它会在您键入时进行搜索。我不知道这个 UI 模式是否有名字,应该有。

动态搜索与 TextChanged 事件挂钩。但关键是,当用户正在输入文本时,我不想在文本被主动更改时进行搜索。我想搜索更改何时完成,何时停止输入。

这对你来说可能也很有趣。

我使用的启发式方法:如果在最后一个 textchange 事件之后经过了 600 毫秒,那么输入已经停止,那就是应该运行搜索的时间。但是如何让代码在 TextChange 事件后运行 600 毫秒。在事件处理程序中不能Thread.Sleep。这只会导致 UI 延迟。

我想出的解决方案是:在 TextChange 事件中使用 Threadpool.QueueUserWorkItem 来排队一个名为 MaybeDoSearch 的工作方法。在该工作人员中,对延迟间隔(600 毫秒)执行 Thread.Sleep。睡眠完成后,检查自上一个 TextChanged 事件以来经过的时间。如果该时间超过 600 毫秒,则实际执行搜索。

看起来像这样

    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();
        }
    }

我的是一个 WinForms 应用程序。因为 MaybeDoSearch() 在工作线程上运行,而不是 UI 线程,所以在 ShowSearchResults() 中,UI 更新必须使用InvokeRequired 进行保护。

在正常打字过程中,一个人会在 600 毫秒内输入 2 或 3 个字符。结果是有 2 或 3 个工作项在单独的线程池线程上排队并运行(主要是睡眠),在任何给定的时刻,当打字活动发生时。

之前有人建议您必须在每次更改时重新扫描所有文本以查找元音。这是运行时的冗余工作,出于效率目的,您通常希望避免这种工作。但是这样代码就简单多了。我遇到了同样的问题,并决定不试图弄清楚文本是如何随着当前 TextChange 事件发生变化的。它发生了变化,因此代码进行了全新的搜索。搜索完成的速度比延迟间隔 (600ms) 快。在你的情况下,计算元音,它会更快。

【讨论】:

  • @Cheeso:因为我还不太熟悉 c# 中的所有语法,所以我第一次看到你的编码时看起来很困难,但我认为你是对的。使用:“System.DateTime _lastChangeInSearchText;”它是在公共表格 1:Form 之后声明的,还是我需要为此创建一个类?谢谢你的建议。我很想试试这个
  • 您不需要新课程。 _lastChangeInSearchText 只是 Form 类中的另一个成员变量。
  • @Cheeso:所以这将属于我添加方法的同一个类?
  • 是的。并且 tbSearch_TextChanged 方法只是一个事件处理程序,在您的 Form 类中,它应该与您的文本框的 TextChanged 事件挂钩。都在同一个班级。
  • @Cheeso:谢谢。我正要尝试你的代码,突然我意识到使用修复编号通常会在以后的代码中出现一些问题。你怎么看?
【解决方案3】:

让我们看看。这可以在所有这些中完成,但某些事件更有可能发生。

KeyDown:在KeyDown中,键通常仍以整数表示。您必须自己映射元音。重复值只触发一次。所以你可能会丢失一些元音。

KeyPressed:在这里您可以得到正确表示的键。如果按下元音,则添加一个。但是如果按下 delbackspace 是否必须减去一个?您不知道删除了哪个键。

KeyUp:同样,表示是一个整数。重复值只会触发。

TextChanged:每当文本更改时触发。在这里你不知道最后按下的键是什么(它可能在文本中的某个位置),所以你必须从头开始重新计算元音的数量。

我会这样做:

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

这样每次文本更改时都会进行计算,此外也可以通过按下按钮来完成。如果您不喜欢直接调用事件函数,请创建一个从两个位置调用的函数。

也许您只想在 TextChanged 中不时执行此操作(请参阅其他答案)。

【讨论】:

  • @Ralph Rickenbach:感谢您的意见。我尝试了 KeyDown 和 TextChanged。似乎它们不起作用。我不确定我是否在这里遗漏了什么。每次我输入元音“a”时,它实际上都不算数。除了我的代码之外,我还需要添加一些代码吗?
  • 那你的密码是什么?要查看代码是否被执行,只需在代码行上设置断点即可。然后,如果它执行了,看看你的代码做了什么。
【解决方案4】:

Keypress 在按键被按下时触发。 (不确定) 当键上升(释放)时触发键 UP(将您的手指从键盘上移开)

【讨论】:

  • @Ahmad Farid:谢谢你的定义。你知道打字时用什么事件来计算字母吗?谢谢
  • 还有KeyDown。 KeyDown 在第一次按下键时被触发,然后(可能有几个)事件 KeyPressed 被触发,这取决于操作系统的键盘重复率。 KeyUp 在释放键时触发。
  • @Ralph Rickenbach:那么 KeyDown 是事件吗?当我将它集成到我的代码中时,我需要知道一个特定的代码吗?或者我可以双击事件 KeyDown 并从那里添加我的代码吗?谢谢
猜你喜欢
  • 2020-03-24
  • 2013-08-09
  • 1970-01-01
  • 2011-05-05
  • 2015-05-16
  • 1970-01-01
  • 2021-08-07
  • 2018-01-14
  • 1970-01-01
相关资源
最近更新 更多