【问题标题】:c# string iterator for showing words one by one [duplicate]c#字符串迭代器,用于一一显示单词[重复]
【发布时间】:2021-09-13 00:28:09
【问题描述】:

我想要做的是一个包含文本框(或其他允许我这样做的东西)的程序,这个文本框将显示我的资源 .txt 文件中的文本,这就像一个单词之后一个或两个单词一个接一个,让用户改善对文本的眼球运动。为了更清楚,文本框将两个两个地显示单词。我可以通过使用字符串数组来做到这一点,但它只适用于列表框,而列表框不适用于这个项目,因为它是垂直的,我需要像我们在书中看到的那样水平文本。

这是显示我想要但我无法使用它的逻辑的代码,当我单击按钮时它会停止。

{
    public Form1()
    {
        InitializeComponent();
    }

    string[] kelimeler;


  

    private void button1_Click(object sender, EventArgs e)
    {
        const char Separator = ' ';
        kelimeler = Resource1.TextFile1.Split(Separator);

    }


    private void button2_Click(object sender, EventArgs e)
    {
        for (int i = 0; i< kelimeler.Length; i++)
        {
            textBox1.Text += kelimeler[i]+" " ;

            Thread.Sleep(200);


        }


        
    }
}

【问题讨论】:

  • 你有一个循环,其内容更新 I 然后休眠。在传统的 Windows 代码中,UI 只会在消息处理程序(此处为按钮单击处理程序)返回之后 更新。如果您等待足够长的时间让所有睡眠结束(kelimeler.Length 有多大),您应该会看到最后一个字。解决此问题的传统方法是将消息发布回窗口并让该处理程序更新屏幕。但是,asyncawait 可能可以解决问题。使您的处理程序async 并使用await Task.Delay(200) 而不是Thread.Sleep
  • 看看微软的反应式框架。然后你可以这样做:kelimeler.ToObservable().Scan("", (a, x) =&gt; $"{a} {x}").Zip(Observable.Interval(TimeSpan.FromMilliseconds(200.0)), (s, z) =&gt; s).ObserveOn(textBox1).Subscribe(x =&gt; textBox1.Text = x);

标签: c# string text split iterator


【解决方案1】:

以下是使用 asyncawait 的方法。它使用async void,这通常是不受欢迎的,但这是我知道如何使按钮处理程序异步的唯一方法。

我不会从资源中找出起始字符串,我只是这样做:

private const string Saying = @"Now is the time for all good men to come to the aid of the party";

而且,我雕刻了字符串的检索和拆分它自己的功能(使用yield return 来制造枚举器)。

private IEnumerable<string> GetWords()
{
    var words = Saying.Split(' ');
    foreach (var word in words)
    {
        yield return word;
    }
}

那么剩下的就是将单词粘贴在文本框中的代码。此代码执行我认为您想要的操作(将第一个单词放入文本框中,稍作停顿,放入下一个单词,暂停等)。

private async void button3_Click(object sender, EventArgs e)
{
    textBox4.Text = string.Empty;
    foreach (var word in GetWords())
    {
        textBox4.Text += (word + ' ');
        await Task.Delay(200);
    }
}

【讨论】:

  • 感谢您对我稍作改动的代码,现在我可以将它与资源文件一起使用,它可以按我的意愿工作。作为下一步,我试图找出如何回到文本框的顶部,因为当文本框充满单词时,滚动条就会出现,我不希望这样。我想让它像书页一样,我的意思是当文字到达文本框的底部时,它应该自动转到顶部。如果你知道,你能帮我吗?
  • 这将是另一个问题。这并不容易,Textbox 控件非常愚蠢(它是传统 User32 文本框控件的薄包装)。 Lines 属性返回一个字符串数组,表示控件中的文本行。您可以测量控件(如果其大小发生变化,则重新测量),计算可用行数,然后监视 Lines 数组以查看控件中的行数是否超过可用空间,然后从那里开始。这并不容易(而且看起来有点被破解)
  • 行会很有用,但我从中获取文本的文本文件不是按顺序编写的,我的意思是它从第 1 行开始,这真的很重要。第 1 行和第 2 行之间有将近 500 个单词,所以它没有用。
  • 如果可能的话,我可以使用richtextbox或其他东西
  • 我不明白。当您在多行文本框中(使用 WordWrap=true)编写单词时,单词将换行。每行你可能会得到 12 个单词。如果你测量你的字符在你的文本框中占据了多少空间(参见Graphics.MeasureString)并计算你在文本框中有多少行(Textbox.Lines.Count),你应该能够知道你什么时候填满了文本框.当您到达 N 行 + 1 时,清空文本框并重新开始填充。或者,如果您想要滚动行为,请将选择设置为最后可能的位置,SelectionWidth=0 和 ScrollToSelection
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
  • 2010-09-19
  • 2017-01-13
  • 1970-01-01
相关资源
最近更新 更多