Visual C # Windows Текстовое поле формы не обновляется автоматически - PullRequest
0 голосов
/ 21 июля 2011

Я пытаюсь закодировать приложение, которое считывает значения из IMU.Я пытаюсь получить разные значения ориентации (то есть направления) IMU в течение 1 секунды при использовании метода getAtr_Click.Однако, хотя это вызывает функцию 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 ]

2 голосов
/ 21 июля 2011

Это потому, что вы взламываете поток пользовательского интерфейса:

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();
}
0 голосов
/ 21 июля 2011

Вы хотите видеть 10 (возможно) различных значений, отображаемых в ваших текстовых полях в течение 1 с, с интервалом в 10 мс, после вызова getAttr_Click ()?

Если да, то это будет путь ксделайте это:

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 (), просто проверяет vn100.CurrentAttutude с интервалами 10 мс.Как только оно имеет ненулевое значение, я подозреваю, что оно остается ненулевым, то есть ваш цикл while () будет пропущен в каждой итерации for (), поэтому Get_Attitude () будет вызываться 10 раз подряд (вероятно) так быстро, чтовы можете видеть только последние значения на экране.

Дело в том, что ваш пользовательский интерфейс останется без ответа каждые 10 мс в течение клика, поэтому вы можете рассмотреть возможность вызова этого getAtr_Click () асинхронно или другого тривиального решения.*

EDIT: На самом деле, это поможет узнать поведение компонента vn100.В случае, если это непредсказуемо, единственное, в чем вы можете быть уверены, это отображать 10 различных значений на расстоянии не менее 10 мс во времени, независимо от того, выполняете ли вы все в потоке пользовательского интерфейса или в другом потоке.Все это связано с поведением vn100.CurrentAttitude ...

0 голосов
/ 21 июля 2011

изменить на:

 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();
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...