매 초마다 업데이트되는 WPF 컨트롤을 만드는 방법은 무엇입니까?
-
05-07-2019 - |
문제
이 질문은 비슷합니다 내가 요청한 또 하나, 그러나이 경우 XAML 또는 View 모델에서 바인딩을 강요하는 것에 대해 알고 싶었지만이 경우 사용자 지정 WPF로 래핑하는 것에 대해 알고 싶습니다. FrameworkElement
.
내가 후에 기능하는 기능은 무언가가 얼마나 오래 일어 났는지를 나타내는 텍스트의 범위입니다.
<TextBlock Text="It happened " />
<my:AgeTextBlock SinceTime="{Binding OccurredAtUtc}" />
<TextBlock Text=" ago" />
이것은 (예를 들어)로 렌더링됩니다.
1 분 13 초 전에 일어났다
a에서 변환하는 코드가 있습니다 TimeSpan
인간이 읽을 수있는 형태로.
매 초마다 UI 업데이트를하려면 정적 사용을 고려하고 있습니다. DispatcherTimer
(아이디어 켄트 부가 아트의 대답).
그래서 여기에 내가 가진 것이 있습니다.
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?
}
의견은 내 문제를 나타냅니다. 이 접근법으로 어떻게 제대로 청소하는지 알 수 없습니다. 아니요 Dispose
이벤트 핸들러를 무시하고 제거하는 메소드.
여기에 권장 패턴은 무엇입니까?
해결책
로드 된 컨트롤 이벤트에서 진드기 이벤트를 구독하고 언로드 된 이벤트에서 구독을 취소하지 않겠습니까?
다른 팁
TextBlock이 Idisposable을 구현하지 않다고해서 인터페이스 요구 사항과 구현을 직접 추가 할 수 없다는 의미는 아닙니다. 당신은 자신을 처분하고 (베이스에서 아무것도 무시하지 않음) 당신의 타이머를 처분 할 수 있습니다.
그런 다음 분명히 AgetextBlock 클래스를 처분 할 책임이 있습니다. 예를 들어 Windows Closing 이벤트 에서이 작업을 수행 할 수 있습니다.
(또는 또는 당신이 따르는 경우 MVVM 패턴, TIMER를보기 모델에 놓으면보기 모델을 idisposable로 만들고보기 모델의 타이머 값에 뷰를 바인딩 할 수 있습니다.)
편집 : 예, 이것에 대해 생각하면, 나는 이것이 Winforms와 달리 사용자 정의 컨트롤이어야한다고 생각하지 않습니다. WPF는 사용자 정의 컨트롤이 필요하지 않으며 대신 내보기 모델에 타이머 속성을 노출시킬 것이라고 생각합니다 ( 아마도 사전 형식화 된 속성이므로 읽기 쉬운 문자열을 가지고있을 수 있습니다.) 해당 속성을 일반 텍스트 상자에 바인딩합니다 - 사용자 정의 컨트롤 없음 - 스타일이나 템플릿을 사용하여 텍스트 상자의 시각적 특성을 조정하여 원하는 방법을 찾을 수 있습니다. . 그 소리는 어때?