【发布时间】:2013-04-22 01:32:26
【问题描述】:
我有一个如下图所示的列表视图。如您所见,我有一列名为Time。 我想知道如何自动更新时间。
例如航班代码ABC123的时间应该在1分钟后从3分钟变为4分钟。
【问题讨论】:
我有一个如下图所示的列表视图。如您所见,我有一列名为Time。 我想知道如何自动更新时间。
例如航班代码ABC123的时间应该在1分钟后从3分钟变为4分钟。
【问题讨论】:
查看dispatch timer 并每分钟执行一次记录更新
我会这样做
【讨论】:
Big smart ViewModels, dumb Views, and any model, the best MVVM approach? 包含 WPF 应用程序的代码,其中 ViewModel(和绑定到它的 View)由计时器更新。它每 1 秒(1000 毫秒)出现一次
【讨论】:
编辑 对每分钟都使绑定无效的想法不满意(这可能完全没有根据,并且每分钟都无效,我不知道),所以来了有了一个直接设置内容的“更纯粹”的实现,但保留原件以供参考:
您可以通过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" />`
【讨论】: