0

現在、XAMLで値コンバーターを使用して、ビューモデルのDateTimeフィールドを「x分前」の形式で表示しています。オーバーヘッドをあまり発生させずに定期的に更新する必要があります。いつでも、画面上に1ダース、画面外に数ダースあります。最善の戦略は何ですか?

  1. ビューモデルオブジェクトのコンストラクターで、静的な「ViewRefresher」に登録してもらいます。この静的な「ViewRefresher」は、登録されたフィールドですべてのオブジェクトを定期的に調べ、PropertyChangedハンドラーを起動します。

  2. オブジェクトを保持しているコンテンツ/アイテムコントロールオブジェクトを更新します

  3. 他に何かありますか?

答えを待っている間、私は先に進んで上記の両方のアプローチを試し、それが他の誰かを助ける場合に備えて報告します。

更新: OK、イベントパスに私を入れてくれたcsteinmuellerに感謝します。オブジェクトの登録/登録解除よりもはるかにクリーンです。次の戦略は漏れてはいけないと思います。

public class DateTimeC: INotifyPropertyChanged
{
    public DateTime DT {get; set;}
    public event PropertyChangedEventHandler PropertyChanged;

    public DateTimeC(DateTime dt)
    {
        DT = dt;
        ViewRefresher.FiveSecondsTick += () =>
           { PropertyChanged(this, new PropertyChangedEventArgs("DT")); };
    }

}

public delegate void TickHandler();

public static class ViewRefresher
{
    private static DispatcherTimer dt = new DispatcherTimer();
    private static int counter = 0;

    public static event TickHandler FiveSecondsTick;
    public static event TickHandler OneMinuteTick;

    static ViewRefresher()
    {
        dt.Interval = TimeSpan.FromSeconds(5);
        dt.Tick += Tick;
        dt.Start();
    }

    private static void Tick(object sender, EventArgs e)
    {
        if (FiveSecondsTick != null)
            FiveSecondsTick();

        if (counter++ != 12) return;

        counter = 0;

        if (OneMinuteTick != null)
            OneMinuteTick();
    }
}

フィールドとしてインライン化するのではなく、DateTimeから直接派生できればよかったのですが、封印されています。

更新2:結局のところ、これにはメモリリークがあるようです。DateTimeCをガベージコレクションするには、イベントのフックを解除するか、弱参照を使用する必要があります。

4

1 に答える 1

1

最初のアプローチでSystem.Timerオブジェクトを一緒に選択します(すべてのViewModelは静的クラスのコレクションまたはイベントに登録されます)

Timer timer;
AutoResetEvent autoEvent = new AutoResetEvent(true);
TimerCallback callback = new TimerCallback(MyCallback);

timer = new Timer(callback, autoEvent, new TimeSpan(0), new Timespan(5));
于 2012-05-23T09:20:19.577 に答える