2009-03-29 18 views
3

Ich möchte Zeit in der Bezeichnung anzeigen. Der Etiketteninhalt muss beim Laden des Fensters automatisch aktualisiert werden.WPF: Refresh/Update Kontrolle auf Fenster laden

Ich habe ein einfaches WPF-Fenster mit einem Label-Steuerelement darin. Wie hier dargestellt

<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> 

Ich habe hier, auf den Code sieht: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

Und ich verändern auf diese Weise passen:

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); 
    } 
} 

ich den Code entdeckt habe, funktioniert ziemlich gut, wenn es ausgelöst durch ein button_Click-Ereignis. Ich habe versucht, den Code durch ein Window_Loaded-Ereignis wie dieses zu bekommen, aber vergeblich. Der Fensterinhalt wird nie angezeigt.

Was kann ich tun, um das Etikett automatisch zu aktualisieren, wenn das Fenster geladen wird?

Antwort

3

Das ist völlig normal, weil der OnLoad-Handler in einer Endlosschleife bleibt. Diese Schleife befindet sich im UI-Thread, daher wird das Fenster nie angezeigt.

Zunächst einmal: wickeln Sie Ihre Schleife in eine Backgroundworker, so dass es auf einem separaten Thread läuft.

Ich würde auch den Schleifen-Code in ein separates Objekt Faktor INotifyPropertyChanged implementieren, die eine Eigenschaft mit der Zeit (string) exponiert, diese Eigenschaft das Ereignis PropertyChanged auslösen, wenn es ändert (durch die Schleife). Sie müssten dies natürlich immer noch auf einem separaten Thread tun (zB mit BackgroundWorker). Verwenden Sie eine Bindung, um Ihr spezialisiertes Objekt an das Label zu binden.

Eine andere Taktik würde eine Timer verwenden, die in regelmäßigen Abständen einen Rückruf durchführt, und Sie können das Etikett dort aktualisieren.

+0

Ich habe den Backgroundworker verwendet und es hat getan, was ich wollte! –

3

Ich würde eine Klasse schreiben, die die INotifyPropertyChanged-Schnittstelle mit einer CurrentTime-Eigenschaft implementiert und eine DispatcherTimer-Instanz enthält, die das PropertyChanged-Ereignis ("CurrentTime") regelmäßig auslöst.

Dann legen Sie dieses Objekt in die Ressourcen Ihres Formulars und binden den Inhalt des Labels an die CurrentTime-Eigenschaft.

DispatcherTimer verwendet die Nachrichtenpumpe, sodass keine unnötigen Threads beteiligt sind.

1

Anstatt eine Endlosschleife zu verwenden, verwenden Sie einen DispatcherTimer