Joh*_*aps 7 c# events winforms
我想要的是
每当Windows中的时区更改时,我都想做些事情。
到目前为止我有什么
为此,我实现了事件SystemEvents.TimeChanged,如下所示:
在构造函数中:
SystemEvents.TimeChanged += SystemEvents_TimeChanged;
Run Code Online (Sandbox Code Playgroud)
事件主体:
void SystemEvents_TimeChanged(object sender, EventArgs e)
{
MessageBox.Show("Test1");}
Run Code Online (Sandbox Code Playgroud)
问题是什么
在Windows中更改时间或时区时,不会触发该事件。
我尝试过的
当我在干净的WinForms应用程序中编写以上代码时,一切都按预期工作。但是在我的应用程序中却没有,原因是包含许多其他代码。我看不到我还有其他任何事件,应该阻止上述事件的触发。
我的问题是
有谁知道什么可能导致上述代码无法在我的应用程序中触发,但是在创建仅包含上述代码的新项目/应用程序时按预期工作?
更新1
这是因为我在调用之前在单独的线程中显示了启动屏幕
Application.Run(new FormMain());
Run Code Online (Sandbox Code Playgroud)
然后,SystemEvents会坚持启动屏幕创建的线程,即使在加载应用程序后该线程也会终止。
现在的问题是,是否有一种方法可以告诉SystemEvents,当应用程序加载后,现在应该使用“正确的” UI线程吗?
该问题关于问题UPDATE 1部分,因此原始问题中提供的代码示例正在工作。
我花了一些时间解决这个问题。因此,我没有为您的代码提供完整的概述,我为该解决方案即兴使用了2个WinForms(一个作为启动,另一个作为主要),当然,这只是说明概念的示例。
据我了解,当您启动软件时,它以启动部分作为单独的线程开始,并在启动完成后从FormMain开始。使用,您可以做得更好ApplicationContext
。您可以创建自己的上下文类,该上下文类从该类扩展而来,ApplicationContext
并在该类中使用各自的逻辑声明Splash和FormMain。现在,根据您的情况,您需要确保FormMain在Splash之后的某个时间点启动或类似的操作(我不知道您的软件如何工作/运行)。
在上下文类中,您可以创建要订阅和取消订阅的方法,SystemEvents.TimeChanged
以便您可以聆听时间的变化。我出于演示目的还创建了一个BindingList
演示时间的更改。
现在让我们显示一些代码:
public static void Main()
{
// use own created context
MainApplicationContext context = new MainApplicationContext();
Application.Run(context);
}
// just quick way to demonstrate how we collect time changes
public static BindingList<string> Logs { get; private set; }
private class MainApplicationContext : ApplicationContext
{
private int _formCount;
public MainApplicationContext()
{
Logs = new BindingList<string>();
_formCount = 0;
// splash screen
var splash = new FormSplash();
splash.Closed += OnFormClosed;
splash.Load += OnFormOpening;
splash.Closing += OnFormClosing;
_formCount++;
splash.Show();
// For demo, make some logic that close splash when program loaded.
Thread.Sleep(2000);
var main = new FormMain();
main.Closed += OnFormClosed;
main.Load += OnFormOpening;
main.Closing += OnFormClosing;
_formCount++;
splash.Close();
main.Show();
}
private void OnFormOpening(object sender, EventArgs e)
{
SystemEvents.TimeChanged += SystemEvents_TimeChanged;
}
private void OnFormClosing(object sender, CancelEventArgs e)
{
SystemEvents.TimeChanged -= SystemEvents_TimeChanged;
}
private void OnFormClosed(object sender, EventArgs e)
{
_formCount--;
if (_formCount == 0)
{
ExitThread();
}
}
private void SystemEvents_TimeChanged(object sender, EventArgs e)
{
var text = $"TimeChanged, Time changed; it is now {DateTime.Now.ToLongTimeString()}";
Logs.Add(text);
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我们的FormMain中,创建名为listbox的框LogListBox
:
public FormMain()
{
InitializeComponent();
Load += ListChanged;
}
// this keep list of time changes events updated if changed this could be log or some thing else.
private void ListChanged(object sender, EventArgs e)
{
LogListBox.DataSource = Program.Logs;
}
Run Code Online (Sandbox Code Playgroud)
文献资料