You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

机场显示屏应用开发:ListBox航班状态定时自动切换实现求助

解决机场显示屏应用的航班状态自动切换问题

我来帮你搞定这个自动状态切换的问题!你现在的核心困扰是把航班数据当成纯字符串塞进ListBox,没法跟踪每个航班的状态变化时间对吧?咱们一步步来调整:

第一步:把航班数据封装成对象

首先得给每个航班建个“档案”,用类来封装它的所有信息,包括状态切换的时间点,这样才能知道什么时候该更新状态:

public class Flight
{
    public string FlightNumber { get; set; }
    public string Destination { get; set; }
    public string CurrentStatus { get; set; }
    public DateTime NextStatusChangeTime { get; set; }

    // 定义状态切换规则:当前状态 → 下一个状态 + 间隔分钟数
    private readonly Dictionary<string, (string NextStatus, int MinutesUntilChange)> _statusRules = new()
    {
        { "Check-In", ("Boarding", 10) },
        { "Boarding", ("Ready-To-Takeoff", 10) },
        { "Ready-To-Takeoff", ("Departed", 5) } // 可按需扩展更多状态
    };

    // 检查是否需要切换状态,并更新信息
    public bool UpdateStatusIfNeeded()
    {
        if (!_statusRules.ContainsKey(CurrentStatus))
            return false;

        if (DateTime.Now >= NextStatusChangeTime)
        {
            var rule = _statusRules[CurrentStatus];
            CurrentStatus = rule.NextStatus;
            // 设置下一次状态切换的时间
            NextStatusChangeTime = DateTime.Now.AddMinutes(rule.MinutesUntilChange);
            return true;
        }
        return false;
    }

    // 重写ToString方法,让ListBox能直接显示航班信息
    public override string ToString()
    {
        return $"{FlightNumber} {Destination} {CurrentStatus}";
    }
}

第二步:修改数据加载逻辑

原来的方法只是读字符串,现在要把每行解析成Flight对象,初始化状态和切换时间:

private void LoadFlightsFromFile()
{
    listBox1.Items.Clear(); // 先清空原有数据

    string[] lines = File.ReadAllLines(@"D:\FlightsSchedule\flights.txt");
    foreach (string line in lines)
    {
        string[] parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length >= 3)
        {
            Flight flight = new Flight
            {
                FlightNumber = parts[0],
                Destination = parts[1],
                CurrentStatus = parts[2]
            };
            // 初始化第一次状态切换的时间
            if (_statusRules.TryGetValue(parts[2], out var rule))
            {
                flight.NextStatusChangeTime = DateTime.Now.AddMinutes(rule.MinutesUntilChange);
            }
            listBox1.Items.Add(flight);
            Thread.Sleep(500); // 保留原来的加载延迟效果
        }
    }
}

第三步:添加定时器自动检查状态

用WinForms自带的Timer定期检查所有航班的状态,这样不会阻塞UI线程:

private Timer _statusUpdateTimer;

// 在窗体加载时初始化定时器
private void Form1_Load(object sender, EventArgs e)
{
    _statusUpdateTimer = new Timer();
    _statusUpdateTimer.Interval = 60000; // 每分钟检查一次(可按需调整,比如10秒)
    _statusUpdateTimer.Tick += StatusUpdateTimer_Tick;
    _statusUpdateTimer.Start();
}

private void StatusUpdateTimer_Tick(object sender, EventArgs e)
{
    bool hasUpdated = false;
    // 遍历所有航班,检查是否需要更新状态
    foreach (Flight flight in listBox1.Items)
    {
        if (flight.UpdateStatusIfNeeded())
        {
            hasUpdated = true;
        }
    }
    // 如果有状态变化,刷新ListBox显示
    if (hasUpdated)
    {
        listBox1.Refresh();
    }
}

第四步:调整按钮点击事件

注意操作UI控件要回到UI线程,避免跨线程异常:

private void button1_Click(object sender, EventArgs e)
{
    Thread thrd = new Thread(() =>
    {
        // 用Invoke切换回UI线程执行加载操作
        this.Invoke(new Action(LoadFlightsFromFile));
    });
    thrd.Start();
}

为什么原来的方法行不通?

你之前直接把字符串加到ListBox,相当于只保存了当前状态的“快照”,没有记录每个航班的状态切换规则和时间点。Thread.Sleep只是延迟添加数据,根本没法实现定时检查状态的功能。用对象封装后,我们才能跟踪每个航班的生命周期,定时器则负责定期触发状态更新。


内容的提问来源于stack exchange,提问作者Analyzer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:44:25