当我尝试找到控件并启用它时,我终于摆脱了所有错误消息。
在属性窗格中,我在主窗口上禁用了一个按钮。
这段代码运行成功,虽然令人讨厌,因为每一秒我都有它给我另一个msgbox来显示代码被触发。但它没有启用按钮。我是C#的新手,所以对我来说它看起来像阿拉伯语。在VB中它只是:
btnMyButton.Enabled = True
这是我背后的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = 1000; // 1000 ms is one second
myTimer.Start();
}
public void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
DateTime today3am = now.Date.AddHours(3);
if (DateTime.Today == today3am.Date && now >= today3am)
{
MessageBox.Show("Code is being triggered");
btnMyButton.IsEnabled = true;
}
}
}
已解决:回应建议:(已完成工作)
public void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
DateTime today3am = now.Date.AddHours(3);
if (DateTime.Today == today3am.Date && now >= today3am)
{
MessageBox.Show("Button Should Enable");
this.Dispatcher.Invoke(() => {
btnMyButton.IsEnabled = true;
});
}
}
答案 0 :(得分:2)
当我复制并粘贴您提供并运行的代码时,在尝试设置IsEnabled
属性时,我得到(正如预期的)异常:
调用线程无法访问此对象,因为另一个线程拥有它。
这是标准的"错误的线程"例外。您没有看到异常(显然),因为您没有在调试器中运行。 Timer
线程捕获异常并忽略它。
解决问题的一种方法是,按照其他人的建议,使用Dispatcher.Invoke()
:
public void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
DateTime today3am = now.Date.AddHours(3);
if (DateTime.Today == today3am.Date && now >= today3am)
{
Dispatcher.Invoke(() => btnMyButton.IsEnabled = true);
}
}
但是,由于问题基本上是由于您使用System.Timers.Timer
类引起的,因此使用正确的计时器类System.Windows.Threading.DispatcherTimer
更有意义:
public MainWindow()
{
InitializeComponent();
var myTimer = new DispatcherTimer();
myTimer.Tick += DisplayTimeEvent;
myTimer.Interval = TimeSpan.FromSeconds(1);
myTimer.Start();
}
public void DisplayTimeEvent(object source, EventArgs e)
{
DateTime now = DateTime.Now;
DateTime today3am = now.Date.AddHours(3);
if (DateTime.Today == today3am.Date && now >= today3am)
{
btnMyButton.IsEnabled = true;
}
}
答案 1 :(得分:1)
尝试使用Dispatcher
。可能是GUI阻止了代码中控件的更改。 Dispatcher
协调对来自多个线程的元素的访问:
this.Dispatcher.Invoke(() => {
btnMyButton.IsEnabled = true;
});
答案 2 :(得分:0)
我认为你需要在Dispatcher线程上设置属性,因为你不在事件处理程序的UI线程上