Question

Cette question est similaire à une autre que j'ai posée , mais dans ce cas, je souhaitais savoir comment forcer une liaison mise à jour à partir de XAML ou d’un modèle de vue, dans ce cas, j'aimerais savoir comment intégrer cela dans un WPF FrameworkElement personnalisé.

La fonctionnalité que je recherche est une étendue de texte indiquant le temps écoulé. Quelque chose s'est passé.

<TextBlock Text="It happened " />
<my:AgeTextBlock SinceTime="{Binding OccurredAtUtc}" />
<TextBlock Text=" ago" />

Ceci rendrait comme (par exemple):

  

Cela s'est passé il y a 1 minute 13 secondes

J'ai un code qui convertit un TimeSpan en un formulaire lisible par l'homme.

Pour que l'interface utilisateur soit mise à jour toutes les secondes, je songe à utiliser un DispatcherTimer statique (idée issue de La réponse de Kent Boogaart ).

Alors voici ce que j'ai:

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

Le commentaire indique mon problème. Je ne vois pas comment je pourrais nettoyer correctement avec cette approche. Aucune méthode Dispose ne permet de remplacer et de supprimer le gestionnaire d'événements.

Quel est le modèle recommandé ici?

Était-ce utile?

La solution

Pourquoi ne pas souscrire à l'événement Tick dans l'événement Loaded du contrôle et se désabonner de l'événement Unloaded?

Autres conseils

Ce n'est pas parce que TextBlock n'implémente pas IDisposable que vous ne pouvez pas ajouter l'exigence d'interface et l'implémentation vous-même. Vous pouvez implémenter vous-même (sans rien remplacer de la base) et y déposer votre chronomètre.

Vous serez évidemment responsable de la suppression de votre classe AgeTextBlock. Vous pourrez le faire dans votre événement de fermeture de Windows par exemple ou quelque chose comme ça.

(Si vous suivez le modèle de MVVM et mettez votre minuterie sur le modèle de vue, vous pouvez rendre votre modèle de vue IDisposable et lier simplement la vue à la valeur de minuterie du modèle de vue.)

[Edit: Ouais, en réfléchissant à cela, je ne pense pas vraiment que ce devrait être un contrôle personnalisé contrairement à Winforms, WPF n’a pas autant besoin de contrôles personnalisés, mais je pense que j’exposerais une propriété timer view model (peut-être une propriété pré-formatée pour que vous ayez une bonne chaîne lisible) et liez cette propriété à une zone de texte normale - pas de contrôle personnalisé - j'utiliserais alors un style ou un modèle pour modifier les propriétés visuelles de la zone de texte. comment je voulais Comment ça sonne?]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top