winforms 如何在窗体主界面中调用UC控件中的定时器?

jvlzgdj9  于 2023-02-09  发布在  其他
关注(0)|答案(1)|浏览(165)

添加新用户控件时,计时器1未启动。我有1个用户控件(UC_Machine)。加载Form Main时,我使用计时器在查询变量中执行SQL查询,以从表[tbl_FF_Trigger]中获取数据
我有1个用户控件(UC_Machine)。当加载Form Main时,我使用计时器在查询变量中执行SQL查询,以从表[tbl_FF_Trigger]中获取数据

  • UC机器中的代码:
private void UC_Machine_Load(object sender, EventArgs e)
        {
             timer1.Start();
        }
  private void timer1_Tick(object sender, EventArgs e)
        {
            string query = "SELECT CRDName, PartNumber ,DefectName FROM [tbl_FF_Trigger] where Machine = '" + Machine + "'";
            db.fillDataGridView(query, dataGridView1);
            dataGridView1.BackgroundColor = Color.White;
            dataGridView1.RowHeadersVisible = false;
            dataGridView1.Update();
            dataGridView1.Refresh();
        }
  • MAIN格式的代码。将从函数Machine_Infor.GetMachine_Infors()中获取机器信息。然后将根据该信息创建UC_Machine数组。如果数组中的机器尚未存在于面板布局中,则将其添加到面板布局中。

此外,它还检查tbl_FF_Trigger表中是否存在该机器。否则,它将从面板布局中删除该机器。

private void Main_Load(object sender, EventArgs e)
        {
            Get_Infor();
        }
 private void Get_Infor()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 3000; // Thời gian chạy (5000 milliseconds = 5 second)
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }
     private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {

            // Add new item to panellayout if machine have falsecall
            var data = Machine_Infor.GetMachine_Infors();
            var list = new UC_Machine[data.Count];
            int i = 0;
            itemFoods = new List<UC_Machine>();
            itemFoodsFilter = new List<UC_Machine>();
            HashSet<string> existingMachine = new HashSet<string>();
            foreach (var item in data)
            {
                if (!existingMachine.Contains(item.Machine))
                {
                    bool isExisting = false;
                    foreach (UC_Machine uc in myFlowLayoutPanel1.Controls)
                    {
                        if (uc.Machine == item.Machine)
                        {
                            isExisting = true;
                            break;
                        }
                    }

                    if (!isExisting)
                    {
                        list[i] = new UC_Machine();
                        list[i].CRDName = item.CRDName;
                        list[i].Model = item.Model;
                        list[i].Machine = item.Machine;
                        list[i].PartNumber = item.PartNumber;
                        list[i].Workcell = item.Workcell;
                        list[i].CRDName = item.CRDName;
                        list[i].Date = item.Date;
                        itemFoods.Add(list[i]);
                        itemFoodsFilter.Add(list[i]);
                        existingMachine.Add(item.Machine);
                        i++;
                    }
                }
            }
            if (myFlowLayoutPanel1.InvokeRequired)
            {
                myFlowLayoutPanel1.Invoke((MethodInvoker)delegate
                {
                    myFlowLayoutPanel1.Controls.AddRange(list.Where(x => x != null).ToArray());
                });
            }
            else
            {
                myFlowLayoutPanel1.Controls.AddRange(list.Where(x => x != null).ToArray());
            }

            // Remove machine if Falsecall not found
            string maincon = ConfigurationManager.ConnectionStrings["Connstring"].ConnectionString;
            // Connect to the SQL Server database and execute the query to check for the existence of "vnhcmsleaoi05" in the "tbl_FF_Trigger" table.
            using (SqlConnection connection = new SqlConnection(maincon))
            {
                connection.Open();
                foreach (UC_Machine uc in myFlowLayoutPanel1.Controls)
                {
                    string query = "SELECT COUNT(*) FROM tbl_FF_Trigger WHERE Machine = '"+ uc.Machine+"'";
                    using (SqlCommand command = new SqlCommand(query, connection))
                    {
                        int count = (int)command.ExecuteScalar();
                        if (count == 0)
                        {
                            if (myFlowLayoutPanel1.InvokeRequired)
                            {
                                myFlowLayoutPanel1.Invoke((MethodInvoker)delegate
                                {
                                    myFlowLayoutPanel1.Controls.Remove(uc);
                                    itemFoods.Remove(uc);
                                    uc.Dispose();

                                });
                            }
                            else
                            {
                                myFlowLayoutPanel1.Controls.Remove(uc);
                                itemFoods.Remove(uc);
                                uc.Dispose();
                            }
                            break;
                        }
                    }
                }
            }

        }

当加载表单时,代码工作正常。当tbl_FF_Trigger添加新值时,myFlowLayoutPanel 1新UC_Machine,但计时器1未启动。我知道这一点,因为数据视图在新添加的UC_Machine中没有数据。我希望当myFlowLayoutPanel 1添加1 UC_Machine时,计时器1将启动。任何人对此情况有任何建议或解决方案,请帮助我。非常感谢!

hfyxw5xn

hfyxw5xn1#

您的问题是如何在窗体Main中调用UC控件中的计时器。主窗体试图从UC调用GetInfo,但考虑到这可能是“向后”的,UC控件应该在获得新信息时通知窗体Main。以下是我的意思:
你的UC有它自己的timer1(我们会让timer1 * 启动 * 别担心)。主窗体需要的是当一个新的查询在一个UC中可用时被 * 通知 *。给主窗体自己的计时器会干扰其他有序的过程。考虑在你的UC中创建一个事件,如图所示,每当UC完成一个新的查询时就触发它。

用户控制计算机

示例:UC启动自己的timer1,并在新查询完成时触发RecordsChanged事件。

public partial class UserControlMachine : UserControl
{
    public UserControlMachine()=>InitializeComponent();
    public BindingList<Record> Records { get; } = new BindingList<Record>();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        timer1 = new Timer { Interval = 2500 };
        timer1.Tick += onTimer1Tick;
        timer1.Start();
        dataGridView1.DataSource = Records;
        Records.Add(new Record()); // <- Auto-generate columns
        dataGridView1.Columns[nameof(Record.DefectName)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    private System.Windows.Forms.Timer timer1;
    private void onTimer1Tick(object sender, EventArgs e) => queryDB();
    private void queryDB()
    {
        // S I M U L A T E D    Q U E R Y    R E S U L T
        Records.Clear();
        for (int i = 0; i < Rando4Test.Next(1,5); i++)
        {
            Records.Add(new Record
            {
                CRDName = $"CRD-{(char)Rando4Test.Next(65,70)}{Rando4Test.Next(100, 200)}"
            });
        }
        // Notify the Main Form that something has changed.
        RecordsChanged?.Invoke(this, EventArgs.Empty);
    }
    public event EventHandler RecordsChanged;
    // For testing purposes
    public static Random Rando4Test { get; } =  new Random();
}

主窗体

主窗体所要做的就是侦听RecordsChanged事件。

public partial class Form1 : Form
{
    public Form1() => InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        // Simulation: Add 2 machines
        for (int i = 0; i < 2; i++)
        {
            var machine = new UserControlMachine
            {
                Size = new Size(myFlowLayoutPanel1.Width - SystemInformation.VerticalScrollBarWidth, 200),
                BorderStyle = BorderStyle.FixedSingle,
            };
            myFlowLayoutPanel1.Controls.Add(machine);
            // Listen for new query results
            machine.RecordsChanged += onAnyUCRecordsChanged;
        }
    }
    private void onAnyUCRecordsChanged(object sender, EventArgs e)
    {
        int totalDefects = 0;
        foreach (var machine in myFlowLayoutPanel1.Controls.OfType<UserControlMachine>())
        {
            totalDefects += machine.Records.Count;
        }
        Text = $"Main Form - Total Defects: {totalDefects}";
    }
}

何处Record类表示DataGridViewRow

public class Record
{
    public string PartNumber { get; set; } = 
        Guid.NewGuid().ToString().Substring(0, 13).ToUpper();
    public string CRDName { get; set; }
    public string DefectName { get; set; } = "Unknown Error";
}

相关问题