3

下の図のようなリストビューがあります。ご覧のとおり、 Timeという列が 1 つあります。時刻を自動的に更新する方法を知りたいです。

たとえば、フライト コード ABC123 の時刻は、1 分後に 3 分から 4 分に変わるはずです。

フライト一覧表示

4

3 に答える 3

1

Edit は、バインドを毎分無効にするという考えに満足していませんでした (完全に根拠のないものである可能性があり、毎分無効にすることは問題ありません。私にはわかりません)。そのため、コンテンツを直接設定する「より純粋な」実装を考え出しました。ただし、参照用にオリジナルを残しました:

を介してそれを行うことができますAttachedBehaviour。以下で開始できるはずです。

public static class TimeAgoBehaviour {

    static Lazy<DispatcherTimer> LazyTimer = new Lazy<DispatcherTimer>(() => {
        DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(1) };
        timer.Start();
        return timer;
    });
    static ConcurrentDictionary<int, EventHandler> Events = new ConcurrentDictionary<int, EventHandler>();

    public static DateTime GetTimeAgo(ContentControl obj) {
        return (DateTime)obj.GetValue(TimeAgoProperty);
    }

    public static void SetTimeAgo(ContentControl obj, DependencyProperty value) {
        obj.SetValue(TimeAgoProperty, value);
    }

    public static readonly DependencyProperty TimeAgoProperty = DependencyProperty.RegisterAttached("TimeAgo",
        typeof(DateTime), typeof(TimeAgoBehaviour),
        new UIPropertyMetadata(DateTime.UtcNow, OnTimeAgoChanged));

    private static void OnTimeAgoChanged(object sender, DependencyPropertyChangedEventArgs e) {
        var newDate = (DateTime)e.NewValue;

        EventHandler oldEvent;
        if (Events.TryRemove(sender.GetHashCode(), out oldEvent)) {
            LazyTimer.Value.Tick -= oldEvent;
        }

        if (DateTime.MinValue == newDate) {
            return;
        }

        var doUpdate = new EventHandler((s, args) => {
            ContentControl control = sender as ContentControl;
            control.Content = TimeAgoConverter.GetTimeAgo(newDate);
        });

        doUpdate(sender, new EventArgs());

        Events.TryAdd(sender.GetHashCode(), doUpdate);
        LazyTimer.Value.Tick += doUpdate;
    }
}

Xaml:

<Label local:TimeAgoBehaviour.TimeAgo="{Binding InitialisedDate}" />



以下は元の応答です。


を介してそれを行うことができますAttachedBehaviour。これにより、バインディングが毎分無効になり、再評価が行われます。必要な場所を拡張する開始点として、以下が機能します。

コード:

public static class PropertyToInvalidateBehaviour {

    static Lazy<DispatcherTimer> LazyTimer = new Lazy<DispatcherTimer>(() => {
        DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(1) };
        timer.Start();
        return timer;
    });
    static ConcurrentDictionary<int, EventHandler> Events = new ConcurrentDictionary<int, EventHandler>();

    public static DependencyProperty GetPropertyToInvalidate(DependencyObject obj) {
        return (DependencyProperty)obj.GetValue(PropertyToInvalidateProperty);
    }

    public static void SetPropertyToInvalidate(DependencyObject obj, DependencyProperty value) {
        obj.SetValue(PropertyToInvalidateProperty, value);
    }

    public static readonly DependencyProperty PropertyToInvalidateProperty = DependencyProperty.RegisterAttached("PropertyToInvalidate",
      typeof(DependencyProperty), typeof(PropertyToInvalidateBehaviour),
      new UIPropertyMetadata(null, OnPropertyToInvalidateChanged));

    private static void OnPropertyToInvalidateChanged(object sender, DependencyPropertyChangedEventArgs e) {
        var propertyToInvalidate = e.NewValue as DependencyProperty;

        EventHandler oldEvent;
        if (Events.TryRemove(e.Property.GetHashCode(), out oldEvent)) {
            LazyTimer.Value.Tick -= oldEvent;
        }

        if (null == propertyToInvalidate) {
            return;
        }

        var doUpdate = new EventHandler((s, args) => {
            BindingExpression binding = BindingOperations.GetBindingExpression(sender as DependencyObject, propertyToInvalidate);
            binding.UpdateTarget();
        });

        Events.TryAdd(e.Property.GetHashCode(), doUpdate);
        LazyTimer.Value.Tick += doUpdate;
    }
}

Xaml:

<Label Content="{Binding Path=InitialisedDate, Converter={StaticResource cnvTimeAgo}}" local:PropertyToInvalidateBehaviour.PropertyToInvalidate="Label.Content" />`
于 2013-04-20T17:11:11.977 に答える
1

ビッグ スマート ViewModels、ダム ビュー、および任意のモデル、最高の MVVM アプローチ? ViewModel (およびそれにバインドされた View) がタイマーによって更新される WPF アプリのコードが含まれています。1秒(1000ミリ秒)ごとに存在します

于 2013-04-20T16:45:22.060 に答える
1

ディスパッチ タイマーを調べて、1 分ごとにレコードを更新する

それが私がすることです

于 2013-04-20T13:46:43.277 に答える