0

我来自嵌入式 C 编程,我对 oop、任务、线程、ecc 完全不了解。我正在弄清楚 C# 和 oop 的基本概念,并想尝试编写一个简单的秒表。

目标:使用按钮切换秒表状态并显示按钮本身内部的值。

到目前为止,我已经做到了这一点:

namespace Cronometro
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        }
    }

    public class MyTimerClass
    {
        private DateTime TimeValue;
        private System.Timers.Timer TimerObj;
        private const int TimeInterval = 1;

        public MyTimerClass()
        {
            TimeValue new DateTime(0, 0, 0, 0, 0, 0, 0, DateTimeKind.Local);
            TimerObj = new System.Timers.Timer(TimeInterval);
            TimerObj.AutoReset = true;

            TimerObj.Elapsed += TimerObj_Elapsed;
        }

        private void TimerObj_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            TimeValue = TimeValue.AddMilliseconds((double)TimeInterval);
        }

        public void Start()
        {
            TimerObj.Start();
        }
        public void Stop()
        {
            TimerObj.Stop();
        }
    }
}

到了这一点,我只是想用 Button.Content 打印值,但似乎我不能在MainWindow课堂外使用它。

我应该怎么办?我开始考虑在主类中创建一个任务并等待计时器事件打印值,但我对线程和任务一无所知。

4

3 回答 3

0

目前还不清楚您的意思,因为目前您根本无法在MainWindow课堂上使用它。只需通过公共函数公开该值,您就可以在任何您想要的地方获取实例的值。

namespace Cronometro
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var x = new MyTimerClass();       // <<<
            x.Start();                        // <<<
            var timeValue = x.GetTimeValue(); // <<<
        }
    }

public class MyTimerClass
{
    private DateTime TimeValue;
    private System.Timers.Timer TimerObj;
    private const int TimeInterval = 1;

    public MyTimerClass()
    {
        TimeValue new DateTime(0, 0, 0, 0, 0, 0, 0, DateTimeKind.Local);
        TimerObj = new System.Timers.Timer(TimeInterval);
        TimerObj.AutoReset = true;

        TimerObj.Elapsed += TimerObj_Elapsed;
    }

    private void TimerObj_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        TimeValue = TimeValue.AddMilliseconds((double)TimeInterval);
    }

    public DateTime GetTimeValue() // <<<
    {                              // <<<
        return TimeValue;          // <<<
    }                              // <<<

    public void Start()
    {
        TimerObj.Start();
    }
    public void Stop()
    {
        TimerObj.Stop();
    }
}
于 2020-04-01T18:24:37.787 回答
0

首先,您不必编写自己的 Stopwatch 类。DotNet 有自己的: https ://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.8

其次,尝试理解 async/await 模式: https ://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

因此,您可以执行以下操作: https ://wouterdekort.com/2013/10/01/async-and-await-and-the-ui-thread/

于 2020-04-01T18:27:58.650 回答
0

填充按钮文本的一种方法是在类中创建一个事件MyTimerClass,并从类内部将一个侦听器委托附加到它MainWindow

然后,触发 inTimerObj_Elapsed中的事件MyTimerClass,以便调用 in 中的事件处理程序MainWindow,您将有机会填充按钮。

但是,除了“练习课”之外,还有其他事情需要处理。因为您使用的是线程池计时器,所以计时器的Elapsed事件处理程序是从工作线程调用的。在 GUI 应用程序中,只有主 / UI 线程可以与控件交互。所以很有可能,您在尝试设置时会遇到异常Button.Text。您需要将 set 操作编组到 UI 线程。

坦率地说,如果您正在练习用 C# 编写课程,我建议您使用控制台应用程序而不是 GUI 应用程序开始。如果人们同时在桌面上抛出太多你不知道的概念,这可能不是一个好主意。

于 2020-04-02T10:28:48.500 回答