Pregunta

Esta pregunta es similar a otra que pregunté , pero mientras que en ese caso quería saber acerca de forzar un enlace a actualización desde XAML o un modelo de vista, en este caso me gustaría saber cómo concluir esto en un FrameworkElement personalizado de WPF.

La funcionalidad que busco es una extensión de texto que indica cuánto tiempo hace que sucedió algo.

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

Esto se representaría como (por ejemplo):

  

Sucedió hace 1 minuto y 13 segundos

Tengo un código que convierte de TimeSpan a la forma legible por humanos que se muestra.

Para que la interfaz de usuario se actualice cada segundo, estoy considerando usar un DispatcherTimer estático (idea de la respuesta de Kent Boogaart ).

Entonces, esto es lo que tengo:

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

El comentario indica mi problema. No puedo ver cómo limpiaría correctamente con este enfoque. No existe un método Dispose para anular y eliminar el controlador de eventos.

¿Cuál es el patrón recomendado aquí?

¿Fue útil?

Solución

¿Por qué no suscribirse al evento Tick en el evento Loaded del control y darse de baja en el evento Noloaded?

Otros consejos

El hecho de que TextBlock no implemente IDisposable no significa que no pueda agregar el requisito de interfaz y la implementación usted mismo. Puede implementar desechar usted mismo (sin anular nada de la base) y desechar su temporizador allí.

Obviamente será responsable de deshacerse de su clase AgeTextBlock. Podría hacer esto en su evento de cierre de Windows, por ejemplo, o algo así.

(Alternativamente, si sigue el patrón MVVM , y ponga su temporizador en el modelo de vista, puede hacer que su ID de modelo de vista sea desechable y simplemente vincular la vista al valor del temporizador en el modelo de vista).

[Editar: Sí, pensando en esto, realmente no creo que deba ser un control personalizado a diferencia de Winforms, WPF no tiene tanta necesidad de controles personalizados, en cambio creo que expondría una propiedad de temporizador en mi ver modelo (posiblemente una propiedad preformateada para que tenga una buena cadena legible) y vincular esa propiedad a un cuadro de texto normal, sin control personalizado, entonces usaría un estilo o plantilla para ajustar las propiedades visuales del cuadro de texto para mirar como queria ¿Cómo suena eso?]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top