【问题标题】:Timer in C# WinForms App not functioning as intendedC# WinForms 应用程序中的计时器未按预期运行
【发布时间】:2013-11-13 09:52:45
【问题描述】:

我正在使用 Visual Studio 2013 创建 Visual C# Windows Forms 应用程序,但我没有使用 Designer 来设置表单。

我有一个我认为是简单的计时器,它应该暂停我的应用程序几秒钟,以便在用户看到和访问菜单之前显示启动屏幕。但是当我运行调试时,应用程序不会出现在屏幕上,直到计时器完成,然后它已经跳过启动屏幕。我已经研究了不同的方法来做计时器,并试图在这几个小时内寻求帮助,但找不到让它工作的方法。我猜我遗漏了一些非常明显的东西,但作为一个新手,我无法发现它。

任何帮助将不胜感激。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Timers;

namespace SimpleForm
{

    public class TheForm : Form
    {

        private MenuStrip menuStrip;
        private MainMenu menuMain;
        private MenuItem menuBlockFile;
        private MenuItem menuBlockOthers;
        private MenuItem menuItemExit;
        private MenuItem menuItemHints;

        static Bitmap imgIntroBg = null;
        static Bitmap imgMenuBg = null;

        private Panel pnlIntro;
        private Panel pnlMenu;

        static int counter = 1;
        static System.Timers.Timer timer;

        public TheForm()
        {

            FormInitialize();

            MenuInitialize();

            introDisplay();

            MenuDisplay(true);

        }

        private void FormInitialize()
        {

            System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Game));

            this.SuspendLayout();

            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(714, 462);
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.Name = "SimpleForm";
            this.Text = "Simple Form";
            ControlBox = false;
            BackColor = System.Drawing.Color.Black;
            StartPosition = FormStartPosition.CenterScreen;

            this.ResumeLayout(false);

        }


        private void MenuInitialize()
        {

            this.SuspendLayout();

            this.menuStrip = new MenuStrip();
            this.menuMain = new MainMenu();
            this.menuBlockFile = new MenuItem();
            this.menuBlockOthers = new MenuItem();

            this.menuItemExit = new MenuItem();
            this.menuItemHints = new MenuItem();

            this.menuMain.MenuItems.AddRange(new MenuItem[] {
                this.menuBlockFile,
                this.menuBlockOthers});

            this.menuBlockFile.Index = 0;
            this.menuBlockFile.MenuItems.AddRange(new MenuItem[] {
                this.menuItemExit
            } );
            this.menuBlockFile.Text = "File";

            this.menuBlockOthers.Index = 1;
            this.menuBlockOthers.MenuItems.AddRange(new MenuItem[] {
                this.menuItemHints
            });
            this.menuBlockOthers.Text = "Others";

            this.menuItemExit.Index = 0;
            this.menuItemExit.Text = "Exit";
            this.menuItemExit.Click += new System.EventHandler(this.menuItemExit_Click);

            this.menuItemHints.Checked = true;
            this.menuItemHints.Index = 0;
            this.menuItemHints.Text = "Temp";
            this.menuItemHints.Click += new System.EventHandler(this.menuItemExit_Click);

            this.Menu = this.menuMain;

            imgMenuBg = new Bitmap("graphics/layout/menubg.png");
            pnlMenu = new Panel();
            pnlMenu.Name = "pnlMenu";
            pnlMenu.Location = new Point(0, 0);
            pnlMenu.Width = 714;
            pnlMenu.Height = 462;
            pnlMenu.BackgroundImage = imgMenuBg;

            MenuDisplay(false);

            this.ResumeLayout(false);

        }

        private void MenuDisplay(bool display)
        {

            this.menuBlockFile.Visible = display;
            this.menuBlockOthers.Visible = display;
            if (display == true) {
                Controls.Add(pnlMenu);
            } else {
                Controls.Remove(pnlMenu);
            }

        }

        private void introDisplay()
        {

            timer = new System.Timers.Timer();
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Interval = 5*1000;
            timer.Enabled = true;

            imgIntroBg = new Bitmap("graphics/layout/Introbg.png");
            pnlIntro = new Panel();
            pnlIntro.Name = "pnlIntro";
            pnlIntro.Location = new Point(0, 0);
            pnlIntro.Width = 714;
            pnlIntro.Height = 482;
            pnlIntro.BackgroundImage = imgIntroBg;

            timer.Start();

            Controls.Add(pnlIntro);

            while (counter != 0)
            {

            }

            Controls.Remove(pnlIntro);

        }

        private static void timer_Elapsed(object source, ElapsedEventArgs e)
        {
            counter = 0;
            timer.Stop();
        }

        private void menuItemExit_Click(object sender, System.EventArgs e)
        {
            Application.Exit();
        }

    }

}

【问题讨论】:

    标签: c# winforms visual-studio timer


    【解决方案1】:

    while(counter != 0) 部分不是正确的做法。 timer_Elapsed 回调将在计时器完成时触发,因此您添加图像 (Controls.Add(plnIntro);),然后等待计时器的回调触发。那是它完成的时候。此时,只需删除 plnIntro 即可。

    您不必使用while 循环来锁定线程即可工作。

    尝试删除:

    while (counter != 0)
    {
    
    }
    
    Controls.Remove(pnlIntro);
    

    并将Controls.Remove(pnlIntro); 放入定时器回调中:

    private void timer_Elapsed(object source, ElapsedEventArgs e)
    {
        Controls.Remove(pnlIntro);
        timer.Stop();
    }
    

    【讨论】:

    • 对我来说,“Controls.Remove(pnlIntro);”这一行出现了几个错误。一个是An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Controls.get',第二个是An object reference is required for the non-static field, method, or property 'SimpleForm.TheForm.pnlIntro'
    • 对不起,没有看到 timer_Elapsed 回调是静态的,将在回答中修复! :)
    • 另外,定时器对象不一定是静态的,我什至建议它不应该是静态的。
    • 它运行但随后在“Controls.Remove(pnlIntro);”上引发错误。 “用户代码未处理 InvalidOperationException”-“System.Windows.Forms.dll 中发生了“System.InvalidOperationException”类型的异常,但未在用户代码中处理附加信息:跨线程操作无效:控件“pnlIntro”从创建它的线程以外的线程访问。"
    • System.Timers.Timer 可能会创建一个新线程,我不确定具体的类交易。尝试改用 System.Windows.Forms.Timer 看看是否有帮助。
    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    相关资源
    最近更新 更多