2009-06-16 6 views
0

この質問はanother one I askedと似ていますが、その場合はXAMLまたはビューモデルからバインディングを強制的に更新することを知りたがっていますが、この場合はこれをカスタムWPF FrameworkElementにラップすることについて知りたいと思います。毎秒更新するWPFコントロールを作成するにはどうすればよいですか?

私が後にしている機能は、何かが起こったかどうかを示すテキストの範囲です。

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

これは(例えば)としてレンダリングするであろう:それは13秒前、1分起こっ

Iは人間可読にTimeSpanから変換コードを有しますフォームが表示されます。

毎秒UIを更新するには、スタティックDispatcherTimer(アイデアKent Boogaart's answer)を使用することを検討しています。だからここ

は、私が持っているものです。

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)。

ここで推奨されるパターンは何ですか?

答えて

4

コントロールのLoadedイベントでTickイベントを購読し、Unloadedイベントで登録を解除しないのはなぜですか?

2

TextBlockがIDisposableを実装していないという理由だけで、インターフェイス要件と実装を自分で追加することはできません。あなたは自分で処分(ベースから何も上書きしないで)を実装し、あなたのタイマーを処分することができます。

あなたはAgeTextBlockクラスを処分する責任があります。あなたは、例えば、そのようなイベントを閉じるあなたの窓でこれを行うことができます。

(あなたがMVVM patternに従うと、ビューモデルのあなたのタイマーを置く場合は代わりに、あなたはあなたのビューモデルIDisposableを作ることができるとちょうどビューモデルにタイマー値にビューをバインドします。)

[編集:ええ、これについて考えてみると、これはWinformsとは違ってカスタムコントロールでなければならないとは思っていません。WPFはカスタムコントロールの必要性がなく、代わりにビューモデルにタイマプロパティを公開すると思います。事前に書式設定されたプロパティを使用して、わかりやすい文字列を読み込みます)、そのプロパティを通常のテキストボックス(カスタムコントロールなし)にバインドします。次に、スタイルやテンプレートを使用してテキストボックスのビジュアルプロパティを調整して、その音はどうですか?]

+0

こんにちはサイモン。答えをありがとう、しかし私は処分のためのインスタンスを追跡することは非常にエレガントであるとは思わない。たとえば、ItemsControl DataTemplate内でこの要素を使用する場合を考えてみましょう。もともと、ビューモデルからプロパティの変更を実行するように設定しましたが、これをかなりの場所で使用し、かなりの量のコードの重複を導入します。だから、私はまだこれを行う良い方法を探しています。 –

+0

あなたの編集に関しては、私は正直に反対します。私のビューモデルはプロパティ(何か起こった時)を持ち、私がそれを提示する方法は、それがどれぐらい前だったかを示す文字列を介しています。ディスパッチャ、文字列の書式設定、プロパティ変更の通知、リソースの割り当てを私のビューモデルに導入する必要はありません。UIでよりうまくやり遂げることができるものをサポートするだけです。 –

+0

@Drew:1)WPFの設計の一部は、アプリケーションのGUI部分に管理されていないメモリが含まれていないようなものです。タイマーをGUIコードに組み込むことで、この前提を破っている(タイマには管理されていないオブジェクトへの参照が含まれている)ので、残念なことに私はこれを解決する上品な方法はないと思う。私はあなたが1つを見つけると非常に興味があります、それは私が数回前に出くわした問題です、そして、あなたが言うように、私は特に満足できる何かを思い付くことができません。おそらく、あなたはWPFのアニメーション機能を利用することができます - これは暗闇の中で非常に野生の刺し傷です。 –

関連する問題