Visual C#Windows窗体文本框不自动更新

时间:2011-07-20 23:04:06

标签: c# winforms visual-studio-2008

我正在尝试编写从IMU读取值的应用程序。我正在尝试使用getAtr_Click方法获得IMU的态度(即方向)的不同值1秒。但是,虽然这是调用Get_Attitude函数,但它只在表单上更改一次文本框值。我如何每次更改? (我希望在文本框中看到10个不同的值闪烁)。

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Timers;
using VectorNav.Devices;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    public static Vn100 vn100 = new Vn100("COM5", 9600);
    // New Vn100 on COM5

    private void Get_Attitude()
        //gets the current yaw, pitch, roll in degrees, and displays
    {
        var attitude = vn100.CurrentAttitude;
        yaw.Text = Convert.ToString(attitude.Ypr.YawInDegs);
        pitch.Text = Convert.ToString(attitude.Ypr.PitchInDegs);
        roll.Text = Convert.ToString(attitude.Ypr.RollInDegs);
    }
    public Form1()
        //connect to the Vn100, set its output to YPR, output at 10Hz
    {
        InitializeComponent();
        vn100.Connect();
        vn100.SetAsyncDataOutputType(Vn100.AsyncOutputType.Ypr, true);
        vn100.SetAsyncDataOutputFreq(10, true);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Get_Attitude();
    }

    private void tare_Click(object sender, EventArgs e)
    {
        vn100.Tare(true);
        vn100.Tare(true); //for some reason it doesn't display the correct Attitude     values w/out a double Tare
        Get_Attitude();
    }

    private void getAtr_Click(object sender, EventArgs e)
    {
        for (int i = 1; i <= 10; i++)
        {
            while (vn100.CurrentAttitude == null)
                Thread.Sleep(10);
            Get_Attitude();
        }
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
        //disconnect from the Vn100 when the box is closed
    {
        vn100.Disconnect();
        base.OnFormClosing(e);
    }

    }
}

3 个答案:

答案 0 :(得分:2)

这是因为你在讨论UI线程:

private void getAtr_Click(object sender, EventArgs e)
{
    for (int i = 1; i <= 10; i++)
    {
        while (vn100.CurrentAttitude == null)
            Thread.Sleep(10); // < - UI can't respond in a sleep
        Get_Attitude();
    }
}

你可以这样做:

private void getAtr_Click(object sender, EventArgs e)
{
    for (int i = 1; i <= 10; i++)
    {
        while (vn100.CurrentAttitude == null)
        {
            Thread.Sleep(10); // < - UI can't respond in a sleep
            Application.DoEvents();
        }
        Get_Attitude();
    }
}

或者您可以强制更新同步发生:

private void tare_Click(object sender, EventArgs e)
{
    vn100.Tare(true);
    vn100.Tare(true); //for some reason it doesn't display the correct Attitude     values w/out a double Tare
    Get_Attitude();
    this.Update();
}

或者您可以使用超时来更新表单而不是循环。

private void tare_Click(object sender, EventArgs e)
{
    System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
    myTimer.Tick += new EventHandler(TimerEventProcessor);
    myTimer.Interval = 10;
    myTimer.Start();
}

void TimerEventProcessor(object sender, EventArgs e)
{
    Get_Attitude();
}

答案 1 :(得分:0)

一旦调用getAttr_Click(),是否要在1秒内看到10个(可能)不同的值显示在文本框中,间隔为10毫秒?

如果是,那就是这样做的方法:

private void getAtr_Click(object sender, EventArgs e)
{
    for (int i = 1; i <= 10; i++)
    {
        while (vn100.CurrentAttitude == null)
            Thread.Sleep(10);
        Get_Attitude();

        Thread.Sleep(10);
    }
}

在您的版本中,调用getAttr_Click()方法的线程只是以10ms的间隔检查vn100.CurrentAttutude。一旦它具有非null值,我怀疑它仍然是非null,这意味着你的while()循环将在每次for()迭代中被跳过,因此Get_Attitude()将被连续调用10次(可能)如此之快你只能看到屏幕上的最后一个值。

事实是,这会在点击期间每隔10毫秒让你的UI无响应,所以你可以考虑异步调用这个getAtr_Click()或其他简单的解决方案。

编辑:实际上,它有助于了解vn100组件的行为。在不可预测的情况下,您唯一可以确定的是在不小于10毫秒的时间内显示10个不同的值,无论您是在UI线程上还是在不同的线程上执行所有操作。这一切都与vn100.CurrentAttitude行为......

有关

答案 2 :(得分:-1)

将其更改为:

 private void Get_Attitude()
    //gets the current yaw, pitch, roll in degrees, and displays
{
    var attitude = vn100.CurrentAttitude;
    yaw.Text = Convert.ToString(attitude.Ypr.YawInDegs);
    pitch.Text = Convert.ToString(attitude.Ypr.PitchInDegs);
    roll.Text = Convert.ToString(attitude.Ypr.RollInDegs);

    vn100.CurrentAttitude = null;
}

private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
    while (vn100.CurrentAttitude == null)
        Thread.Sleep(10);
    Get_Attitude();
    Application.DoEvents();
}
}