Pergunta

Esta questão é semelhante ao outro Perguntei , mas que, neste caso, eu queria saber sobre forçando uma ligação a atualização de XAML ou um modelo de vista, neste caso, eu gostaria de saber sobre embrulho isto em um FrameworkElement WPF personalizado.

A funcionalidade que eu estou atrás é de um intervalo de texto que indica quanto tempo alguma coisa aconteceu.

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

Esta tornaria como (por exemplo):

Aconteceu 1 min 13 seg atrás

Eu tenho o código que converte de um TimeSpan para a forma legível mostrado.

Para ter a atualização UI a cada segundo Estou pensando em usar um DispatcherTimer estático (ideia de resposta de Kent Boogaart).

Então aqui está o que eu tenho:

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

O comentário indica o meu problema. Eu não posso ver como eu limpar corretamente com esta abordagem. Não há nenhum método Dispose para substituir e remover o manipulador de eventos.

O que é o padrão recomendado aqui?

Foi útil?

Solução

Por que não se inscrever para o evento Tick do evento Loaded do controle, e unsubscribe no evento Unloaded?

Outras dicas

Só porque TextBlock não implementa IDisposable não significa que você não pode adicionar o requisito de interface ea implementação si mesmo. Você pode implementar desfazer-se (não substituir qualquer coisa a partir da base) e dispor do seu temporizador de lá.

Você irá, obviamente, em seguida, ser responsável pelo escoamento de sua classe AgeTextBlock. Você poderia fazer isso em suas janelas de fechamento do evento, por exemplo, ou algo parecido.

(Como alternativa, se você seguir o MVVM padrão , e colocar o seu temporizador no modelo de exibição, você pode fazer o seu modelo de vista IDisposable e apenas se ligam a vista para o valor do temporizador sobre o modelo de vista.)

[Edit: Sim, pensando nisso, eu realmente não acho que isso deve ser um controle personalizado ao contrário WinForms, WPF não tem tanta necessidade de controles personalizados, em vez disso eu acho que eu iria expor uma propriedade temporizador no meu vista do modelo (possivelmente uma propriedade pré-formatado para que você tenha uma string legível agradável) e ligam-se que a propriedade de uma caixa de texto normal - sem controle personalizado - então eu iria usar um estilo ou modelo para ajustar as propriedades visuais de caixa de texto para olhar como eu queria. Como isso soa?]

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top