简体   繁体   English

如何在C#中制作动态TextBox

[英]How to make Dynamic TextBox in C#

I have simple FormApplication script that contains button and some TextBoxs. 我有简单的FormApplication脚本,其中包含按钮和一些TextBox。 I want when click on button, one textbox shows some numbers. 我想点击按钮时,一个文本框显示一些数字。 How I can make that dynamic. 我怎样才能做到这一点。

private void button1_Click(object sender, EventArgs e)
{
     txt3.Text = "";
     for (int i = 0; i <50; i++)
     {
         Random random = new Random();
         int randomNumber = random.Next(100, 150);
         txt3.Text = randomNumber.ToString();
     }
}

Now it waits to loop finished and shows latest number. 现在它等待循环完成并显示最新的数字。 I want it shows each number during loop in TextBox seperatly. 我希望它在TextBox中循环显示每个数字。 Seems using Dynamic TextBox is a bit hard, is there any other solution to show this numbers in main form? 似乎使用Dynamic TextBox有点难,有没有其他解决方案以主窗体显示这些数字? Regards, 问候,

you need to do it in separate thread and sleep between each iteration or use a timer. 你需要在单独的线程中进行,并在每次迭代之间休眠或使用计时器。

for example: 例如:

private int counter;
Timer t = new Timer();
Random random = new Random();

private void button1_Click(object sender, EventArgs e)
{
     t.Interval = 100;
         t.Tick += new EventHandler(t_Tick);
         counter = 0;
         t.Enabled = true;
     txt3.Text = "";
}

  void t_Tick(object sender, EventArgs e)
  {
     counter++;
     int randomNumber = random.Next(100, 150);
     txt3.Text = randomNumber.ToString();

     if (counter >= 50)
     {
        t.Enabled = false;
     }
  }

remember this is just one example out of million ways to do it. 记住,这只是百万种方法中的一个例子。 a lot of them are good 很多都很好

another way will be using threads: 另一种方式是使用线程:

private void button1_Click(object sender, EventArgs e)
{
     Thread t = new Thread(new ThreadStart(randomize));
     t.Start();
}

  private void randomize()
  {
     Random random = new Random();

     txt3.Text = "";
     for (int i = 0; i < 50; i++)
     {
        int randomNumber = random.Next(100, 150);

        Invoke(new setTxtHandler(setText), randomNumber.ToString());

        Thread.Sleep(100);
     }
  }

  private void setText(string val)
  {
     txt3.Text = val;         
  }

  private delegate void setTxtHandler(string val);

You have to put the Random outside of the loop since it is seeded with the current time and the loop executes too fast. 你必须将Random放在循环之外,因为它是以当前时间播种的,并且循环执行得太快。

Random random = new Random();
for (int i = 0; i <50; i++)
{
    int randomNumber = random.Next(100, 150);
    txt3.Text = randomNumber.ToString();
}

MSDN MSDN

The random number generation starts from a seed value. 随机数生成从种子开始 If the same seed is used repeatedly, the same series of numbers is generated . 如果重复使用相同的种子, 则生成相同的数字序列 One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. 产生不同序列的一种方法是使种子值与时间相关,从而与每个新的Random实例产生不同的序列。 By default, the parameterless constructor of the Random class uses the system clock to generate its seed value , while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. 默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值 ,而其参数化构造函数可以根据当前时间中的滴答数采用Int32值。 However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. 但是,由于时钟具有有限的分辨率,因此使用无参数构造函数以紧密连续的方式创建不同的随机对象会创建随机数生成器,从而生成相同的随机数序列。

However, since the loop executes very fast you won't see each value anyway, only the last. 但是,由于循环执行速度非常快,因此无论如何都不会看到每个值,只有最后一个。

You can add a panel and then add textboxes onto it 您可以添加一个面板,然后在其上添加文本框

  Random random = new Random();
     for (int i = 0; i <50; i++)
     {
         TextBox t=new TextBox();
         int randomNumber = random.Next(100, 150);
         t.Text = randomNumber.ToString();
    panel.Controls.Add(t);
     }

You should you separate thread and calculate numbers there and update UI then, because now your UI will be updated after calculation is finished. 您应该将线程分开并在那里计算数字然后更新UI,因为现在您的UI将在计算完成后更新。

Eg BackgroundWorker 例如BackgroundWorker

Now it waits to loop finished and shows latest number. 现在它等待循环完成并显示最新的数字。

That's because the operation is single-threaded so there's no UI update until it's completed. 那是因为操作是单线程的,因此在完成之前没有UI更新。 How you would change that depends on whether this is a Windows application or a Web application. 如何更改这取决于这是Windows应用程序还是Web应用程序。

If this is, for example, a Windows Forms application then you want to call Application.DoEvents() to update the UI each time the loop iterates: 例如,如果这是一个Windows窗体应用程序,那么每次循环迭代时,您都希望调用Application.DoEvents()来更新UI:

txt3.Text = randomNumber.ToString();
Application.DoEvents();

This will update the UI's text box each time. 这将每次更新UI的文本框。 (Though it will be very fast, so I doubt you'll even notice it. You might throw in a Thread.Sleep() if you want to slow it down.) (虽然它会非常快,所以我怀疑你甚至会注意到它。如果你想减慢它,你可能会抛出一个Thread.Sleep() 。)

If this is a web application, then you'll want to do this whole thing client-side instead of server-side. 如果这是一个Web应用程序,那么您将希望在客户端而不是服务器端执行此操作。 This is because "updating the UI" in a web application, at least from the server's perspective, means returning the response and waiting for another request. 这是因为至少从服务器的角度来看,在Web应用程序中“更新UI”意味着返回响应并等待另一个请求。 This would result in a lot of back-and-forth between the browser and the server just for updating a single UI element. 这将导致浏览器和服务器之间的大量反复,仅用于更新单个UI元素。 (Which, while it would be slow enough that you'd notice it, it would be a terrible UX.) So in this case you'd want to move the code to JavaScript, which has the benefit of not being single-threaded and would update the UI as you expect it to. (虽然它会很慢,你会注意到它,但它会是一个糟糕的用户体验。)所以在这种情况下,你想要将代码移动到JavaScript,这样做的好处是没有单线程和会像你期望的那样更新UI。

If you want to show each number in the text box, you will need an additional thread which will run the code you have inside button1_Click. 如果要在文本框中显示每个数字,则需要一个额外的线程来运行button1_Click中的代码。 With your current implementation, the GUI will freeze while executing the content. 使用当前的实现,GUI将在执行内容时冻结。 As it's very quick you won't notice it though. 因为它很快你不会注意到它。 From the additional thread, call invoke when setting txt3 to synchronize with the GUI thread. 从附加线程中,在设置txt3时调用invoke以与GUI线程同步。 And add a Thread.Sleep(1000) or similar in the for loop in order to see the numbers change. 并在for循环中添加Thread.Sleep(1000)或类似内容以查看数字更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM