【问题标题】:c# Change Properties throughout Classes and Formsc# 在类和表单中更改属性
【发布时间】:2016-03-18 23:35:46
【问题描述】:

大家好!

不知何故,我对编码很陌生,但偶然发现了一个问题。我自己设法找到了解决方案,但我确信有更好的解决方案!
我会尽量描述我的问题,就像我糟糕的英语技能允许我那样,然后我的解决方案。关键是,我想知道通用中是否有任何解决方案,因为我的解决方案似乎非常特别适合这种情况。
好的,伙计们,我们开始吧!

节目说明

程序本身是由三个窗体组成的,主窗体是“控制中心”或菜单,可以说,另外两个是标签显示的计时器, as you can see here.蓝色定时器递增,而绿色定时器则相反。

当我打开程序时,两个计时器表单也打开了,即使它们没有运行,我也需要它们。显然,我使用 FormMain_Load 方法来显示它们:

private void FormMain_Load(object sender, EventArgs e)
    {
        Form1 timerUp = new Form1();
        timerUp.Show();
        Form2 timerBreak = new Form2();
        timerBreak.Show();
    }

问题

现在,这正是我的问题!第二个有人单击这两个开始按钮之一,我想在表单上启动计时器(因为我将每个计时器的计时器放在自己的表单上)。但是如果我使用

private void buttonStart_Click(object sender, EventArgs e)
    {
        timerUp.timer1.Start();
    }

为了访问“timerUp”变量,我无法访问 FormMain_Load 中的局部变量“Form1 timerUp”。它说“变量在当前上下文中不存在”。

如果有人知道一种可能的解决方案,可以在另一个班级已经打开的表单上简单地打开计时器,我会非常高兴。

我的解决方案

由于已经剧透,即使我对它的设置不满意,我还是设法找到了解决方案。
为了维护我的解决方案,两个计时器在表单打开的第二个开始,例如在 Form1 内部(第一个计时器):

private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Start();
    }

但是,这背后有一些逻辑。我在 mainForm 中设置了一些公共静态布尔值,并通过单击按钮来更改它们。例如:

public partial class FormMain : Form
{
    public static bool timer1 = false;
    public static bool timer2 = false;
    ....

    private void buttonStart_Click(object sender, EventArgs e)
    {
        timer1 = true;
    }
}

现在,再次在 Form1 中,我添加了一些 if 语句来检查这些布尔值。就这样:

private void timer1_Tick(object sender, EventArgs e)
    {
        if (FormMain.timer1)
        {
            ....
        }
    }

显然,该解决方案确实存在一些性能问题:

  • 定时器一直在运行
  • 必须在每个刻度上检查 If 语句

尽管对于我这样一个小程序来说这些基本上是无关紧要的,但我渴望学习如何以正确的方式解决这样的问题。
提前感谢您的任何回复!

【问题讨论】:

  • 您可以将timerUptimerBreak 保留在FormMain 字段中。但是如果用户关闭其中一个表单会发生什么?
  • 您可以在每个子表单中公开timer,而不是使用布尔值。那么你会有buttonStart_Click(...) { timerUp.timer.Start(); }。或者,更封装的方法:在名为 startTimer 的子窗体中定义一个方法,然后在主窗体中运行 timerUp.StartTimer();

标签: c# forms timer


【解决方案1】:

在列出可能的解决方案之前,我强烈建议您详细了解MVC 和/或MVVM(通常用于 WPF)架构模式。他们将指导您如何在 GUI 应用程序中的类和视图之间分配职责。这将是一个陡峭的学习曲线,但最终还是值得的。

  1. 在 MainForm 的类级别直接移动 timerUp 和 timerBreak 变量。这样,您就可以通过对主窗体的引用来访问它们。

     Form1 timerUp;
     Form2 timerBreak;
    
    
      private void MainForm_Load(object sender, EventArgs e)
      {
         timerUp = new Form1();
         timerBreak = new Form2();
         timerUp.Show();
         timerBreak.Show();
      }
    
  2. 如果您认为两个表单的计时器控件将在整个应用程序中被引用,您可以在主表单中保留对它们的引用。

  3. 您可以使用events 通知计时器它们应该启动/停止。这些事件可以在您的 MainForm 中,或者最好在单独的类中。这个单独的类还将包含您的计时器模型(时间、状态等属性),并将通过property change notification 事件通知您的计时器。这在 MVVM 中被大量使用。

【讨论】:

  • 我查看了 MVC,但我非常困惑。我很高兴我有一些关于 C# 的基本知识,但到目前为止没有任何关于 ASP.NET 的知识,但我能找到的几乎所有东西都可以解决这个问题。你有什么可以推荐的 C# 通用的吗?我抓住了基本的想法(以一种特殊的方式格式化代码以使其更容易)但无意中没有理解一件事。
  • 有一些专门针对 WinForms 的示例和信息。 linklinklink。您也可以寻找 MVP 模式,我被告知它更适合 WinForms。
【解决方案2】:

根据我的评论,尝试这样的事情:

public class MainForm
{
    Form1 timerUp = new Form1();
    Form2 timerBreak = new Form2();
    private void MainForm_Load(object sender, EventArgs e)
    {
        timerUp.Show();
        timerBreak.Show();
    }

    private void buttonStart_Click(object sender, EventArgs e)
    {
        timerUp.StartTimer();
    }
}

public class Form1
{
    private Timer _timer = new Timer();
    public void StartTimer()
    {
        _timer.Start();
    }
}

【讨论】:

    【解决方案3】:

    据我了解您的问题,将变量 timerUptimerBreak 从 Main 表单的 Form_Load 事件处理程序移出到类级别就足够了,例如:

    public class FormMain
    {
        // Class level fields
        private Form1 timerUp = new Form1();
        private Form2 timerBreak = new Form2();
    
        private void FormMain_Load(object sender, EventArgs e)
        {
            timerUp.Show();
            timerBreak.Show();
        }
    
        // Use the class level fields wherever you need to
        private void buttonStart_Click(object sender, EventArgs e)
        {
            timerUp.timer1.Start();
        }
    
        // Dispose of the class-level fields when MainForm is disposed
        protected void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (disposing)
            {
                timerUp.Dispose();
                timerBreak.Dispose();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2013-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      相关资源
      最近更新 更多