この質問は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
)。
ここで推奨されるパターンは何ですか?
こんにちはサイモン。答えをありがとう、しかし私は処分のためのインスタンスを追跡することは非常にエレガントであるとは思わない。たとえば、ItemsControl DataTemplate内でこの要素を使用する場合を考えてみましょう。もともと、ビューモデルからプロパティの変更を実行するように設定しましたが、これをかなりの場所で使用し、かなりの量のコードの重複を導入します。だから、私はまだこれを行う良い方法を探しています。 –
あなたの編集に関しては、私は正直に反対します。私のビューモデルはプロパティ(何か起こった時)を持ち、私がそれを提示する方法は、それがどれぐらい前だったかを示す文字列を介しています。ディスパッチャ、文字列の書式設定、プロパティ変更の通知、リソースの割り当てを私のビューモデルに導入する必要はありません。UIでよりうまくやり遂げることができるものをサポートするだけです。 –
@Drew:1)WPFの設計の一部は、アプリケーションのGUI部分に管理されていないメモリが含まれていないようなものです。タイマーをGUIコードに組み込むことで、この前提を破っている(タイマには管理されていないオブジェクトへの参照が含まれている)ので、残念なことに私はこれを解決する上品な方法はないと思う。私はあなたが1つを見つけると非常に興味があります、それは私が数回前に出くわした問題です、そして、あなたが言うように、私は特に満足できる何かを思い付くことができません。おそらく、あなたはWPFのアニメーション機能を利用することができます - これは暗闇の中で非常に野生の刺し傷です。 –