I want to display time in the Label. The label contents needs to be refreshed automatically as the window is loaded.
I have a simple WPF Window with a Label control in it. As illustrated here
<Window x:Class="shoes.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"> <Grid> <Label Margin="12" Name="lblSeconds"></Label> <Button Margin="68,22,135,0" Name="button1" Height="24" VerticalAlignment="Top" Click="button1_Click">Button</Button> </Grid> </Window>
I have looked at the code available here : http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh–update-wpf-controls.aspx
And I modified to fit this way :
public partial class Window1 : Window { private static Action EmptyDelegate = delegate() { }; public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { if (IsLoaded) { LoopingMethod(); } } private void LoopingMethod() { while(true) { lblSeconds.Content = DateTime.Now.ToLongTimeString(); lblSeconds.Refresh(); Thread.Sleep(10); } } } public static class ExtensionMethods { private static Action EmptyDelegate = delegate() { }; public static void Refresh(this UIElement uiElement) { uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); } }
I have discovered the code works pretty well when it is triggered through a button_Click event. I have tried to get the code to run through a Window_Loaded event like this but in vain. The window content is never displayed.
What I can do to get the label updated automatically when the window is loaded?
Which is perfectly normal, because the OnLoad handler stays in an infinite loop. That loop is on the UI thread, so the Window never shows.
First of all: wrap your loop in a
Backgroundworkerso that it runs on a separate thread.I’d also factor out the looping code into a separate object implementing
INotifyPropertyChangedwhich exposes a property with the time (string), have that property raise thePropertyChangedevent when it changes (through the loop). You’d still need to do this on a seperate thread of course (eg usingBackgroundWorker). Use a Binding to bind your specialized object to the label.Another tactic would employ a
Timerwhich does a callback at regular intervals, and you can update the label there.