Reputation: 834
I finally got rid of all the error messages as I attempted ways to find a control and enable it.
In the properties pane I disabled a button on mainwindow.
This code runs successfully, albeit annoyingly, because every second I have it give me another msgbox to show code is being triggered. But it is not enabling the button. I'm new to C# so it looks like arabic to me. In VB it would just be:
btnMyButton.Enabled = True
Here is my code behind:
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;
}
}
}
SOLVED: Response suggested this: (IT WORKED)
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;
});
}
}
Upvotes: 0
Views: 300
Reputation: 70661
When I copy and paste the code you've provided and run it, I get (as expected) an exception when trying to set the IsEnabled
property:
The calling thread cannot access this object because a different thread owns it.
This is the standard "wrong thread" exception. You don't see the exception (apparently) because you're not running in a debugger. The Timer
thread catches the exception and ignores it.
One way to fix the problem is to, as suggested by others, use 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);
}
}
However, since the problem is fundamentally caused by your use of the System.Timers.Timer
class, it makes more sense to just use the correct timer class, 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;
}
}
Upvotes: 2
Reputation: 247
I think you need to set the property on the Dispatcher thread as you are not on the UI thread in the event handler
Upvotes: 0
Reputation: 2277
Try to use Dispatcher
. It may be that the GUI blocks up the change of controls from Code. The Dispatcher
coordinates the access to an element from multiple threads:
this.Dispatcher.Invoke(() => {
btnMyButton.IsEnabled = true;
});
Upvotes: 1