Come effettuare un controllo WPF che si aggiorna ogni secondo?
-
05-07-2019 - |
Domanda
Questa domanda è simile a un'altra che ho chiesto , ma mentre in quel caso volevo sapere come forzare un'associazione a aggiornamento da XAML o da un modello di visualizzazione, in questo caso mi piacerebbe sapere come inserirlo in un
La funzionalità che sto cercando è un arco di testo che indica da quanto tempo è successo qualcosa.
<TextBlock Text="It happened " />
<my:AgeTextBlock SinceTime="{Binding OccurredAtUtc}" />
<TextBlock Text=" ago" />
Questo verrebbe visualizzato come (ad esempio):
È successo 1 minuto e 13 secondi fa
Ho un codice che converte da un TimeSpan
al modulo leggibile dall'uomo mostrato.
Per aggiornare l'interfaccia utente ogni secondo, sto pensando di utilizzare un DispatcherTimer
statico (idea da La risposta di Kent Boogaart ).
Quindi ecco quello che ho:
public class AgeTextBlock : TextBlock
{
private static readonly DispatcherTimer _timer;
static AgeTextBlock()
{
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
}
public AgeTextBlock()
{
_timer.Tick += ...;
}
// How can I unsubscribe from the Tick event to avoid a memory leak?
}
Il commento indica il mio problema. Non riesco a vedere come avrei ripulito correttamente con questo approccio. Non esiste un metodo Dispose
per sovrascrivere e rimuovere il gestore eventi.
Qual è lo schema consigliato qui?
Soluzione
Perché non iscriversi all'evento Tick nell'evento Loaded del controllo e annullare l'iscrizione nell'evento Unloaded?
Altri suggerimenti
Solo perché TextBlock non implementa IDisposable non significa che non puoi aggiungere tu stesso il requisito dell'interfaccia e l'implementazione. Puoi implementare lo smaltimento (non sovrascrivere nulla dalla base) e disporre il tuo timer lì.
Sarai ovviamente responsabile della disposizione della tua classe AgeTextBlock. Potresti farlo nell'evento di chiusura di Windows, ad esempio o qualcosa del genere.
(In alternativa, se segui il modello MVVM e inserisci il tuo timer sul modello di visualizzazione, è possibile rendere IDisposable il modello di visualizzazione e associare la vista al valore del timer sul modello di visualizzazione.)
[Modifica: Sì, pensando a questo, non penso davvero che questo dovrebbe essere un controllo personalizzato a differenza di Winforms, WPF non ha una tale necessità di controlli personalizzati, invece penso che esporrei una proprietà timer sul mio visualizza il modello (possibilmente una proprietà preformattata in modo da avere una buona stringa leggibile) e associa quella proprietà a una normale casella di testo - nessun controllo personalizzato - quindi userei uno stile o un modello per modificare le proprietà visive della casella di testo per guardare come volevo. Come suona?]