绑定到 属性 不与 DispatcherTimer 一起工作
Binding to property not working with DispatcherTimer
我有一些 TextBlock 绑定到具有 DependencyProperty 的 属性。当 DispatcherTimer 更改此 属性 时,TextBlock 不会更新。即使在调试中,我也可以看到 属性 得到更新,但 TextBlock 保持不变。
详情:
我有一个 class:
public class myTimer
{
public System.DateTime Duration { get; set; }
public System.DateTime Elapsed { get; set; }
public System.TimeSpan Remaining {
get {
return Duration.Subtract(new DateTime(Duration.Year, Duration.Month, Duration.Day, Elapsed.Hour, Elapsed.Minute, Elapsed.Second));
}
}
}
我的 xaml 代码后面有一个 myTimer
类型的 DependencyProperty
public static DependencyProperty currentTimerProperty = DependencyProperty.Register("CurrentTimer", typeof(myTimer), typeof(Question));
public myTimer CurrentTimer
{
get { return (myTimer)GetValue(currentTimerProperty); }
set { SetValue(currentTimerProperty, value); }
}
我有三个 TextBlock 绑定到这个 属性:
<TextBlock Style="{StaticResource myTimer}">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:00}:{1:00;00}">
<Binding ElementName="Questionctl" Path="CurrentTimer.Remaining.Minutes"/>
<Binding ElementName="Questionctl" Path="CurrentTimer.Remaining.Seconds"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock Text="{Binding ElementName=Questionctl,Path=CurrentTimer.Duration,StringFormat=HH:mm:ss}"/>
<TextBlock Text="{Binding ElementName=Questionctl,Path=CurrentTimer.Elapsed,StringFormat=HH:mm:ss}"/>
定时器初始化如下:
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan( 0 , 0, 1);
dispatcherTimer.Start();
如此简单,每一秒,它都会将 属性 已用时间增加 1 秒:
CurrentTimer.Elapsed = CurrentTimer.Elapsed.AddSeconds(1);
更新 myTimer
的 Class 定义以实现 INotifyPropertyChanged
看起来像:
public class myTimer : INotifyPropertyChanged
{
private System.DateTime _duration;
public System.DateTime Duration
{
get
{
return _duration;
}
set
{
_duration = value;
RaisePropertyChanged("Duration");
RaisePropertyChanged("Remaining");
}
}
private DateTime _elapsed;
public DateTime Elapsed
{
get { return _elapsed; }
set
{
_elapsed = value;
RaisePropertyChanged("Elapsed");
RaisePropertyChanged("Remaining");
}
}
public System.TimeSpan Remaining
{
get
{
return Duration.Subtract(new DateTime(Duration.Year, Duration.Month, Duration.Day, Elapsed.Hour, Elapsed.Minute, Elapsed.Second));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
如果这是您的实际问题而不是简单化,那么您将遇到另一个问题。
只有当且仅当调度计时器事件恰好以一秒为间隔发生时,您的代码才会起作用。 api.
不能保证这一点
如果您改为在计时器触发时捕获系统时间,即使事件触发之间的时间是零星的,它也会计算出正确的时间。
我有一些 TextBlock 绑定到具有 DependencyProperty 的 属性。当 DispatcherTimer 更改此 属性 时,TextBlock 不会更新。即使在调试中,我也可以看到 属性 得到更新,但 TextBlock 保持不变。
详情: 我有一个 class:
public class myTimer
{
public System.DateTime Duration { get; set; }
public System.DateTime Elapsed { get; set; }
public System.TimeSpan Remaining {
get {
return Duration.Subtract(new DateTime(Duration.Year, Duration.Month, Duration.Day, Elapsed.Hour, Elapsed.Minute, Elapsed.Second));
}
}
}
我的 xaml 代码后面有一个 myTimer
DependencyProperty
public static DependencyProperty currentTimerProperty = DependencyProperty.Register("CurrentTimer", typeof(myTimer), typeof(Question));
public myTimer CurrentTimer
{
get { return (myTimer)GetValue(currentTimerProperty); }
set { SetValue(currentTimerProperty, value); }
}
我有三个 TextBlock 绑定到这个 属性:
<TextBlock Style="{StaticResource myTimer}">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:00}:{1:00;00}">
<Binding ElementName="Questionctl" Path="CurrentTimer.Remaining.Minutes"/>
<Binding ElementName="Questionctl" Path="CurrentTimer.Remaining.Seconds"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock Text="{Binding ElementName=Questionctl,Path=CurrentTimer.Duration,StringFormat=HH:mm:ss}"/>
<TextBlock Text="{Binding ElementName=Questionctl,Path=CurrentTimer.Elapsed,StringFormat=HH:mm:ss}"/>
定时器初始化如下:
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan( 0 , 0, 1);
dispatcherTimer.Start();
如此简单,每一秒,它都会将 属性 已用时间增加 1 秒:
CurrentTimer.Elapsed = CurrentTimer.Elapsed.AddSeconds(1);
更新 myTimer
的 Class 定义以实现 INotifyPropertyChanged
看起来像:
public class myTimer : INotifyPropertyChanged
{
private System.DateTime _duration;
public System.DateTime Duration
{
get
{
return _duration;
}
set
{
_duration = value;
RaisePropertyChanged("Duration");
RaisePropertyChanged("Remaining");
}
}
private DateTime _elapsed;
public DateTime Elapsed
{
get { return _elapsed; }
set
{
_elapsed = value;
RaisePropertyChanged("Elapsed");
RaisePropertyChanged("Remaining");
}
}
public System.TimeSpan Remaining
{
get
{
return Duration.Subtract(new DateTime(Duration.Year, Duration.Month, Duration.Day, Elapsed.Hour, Elapsed.Minute, Elapsed.Second));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
如果这是您的实际问题而不是简单化,那么您将遇到另一个问题。
只有当且仅当调度计时器事件恰好以一秒为间隔发生时,您的代码才会起作用。 api.
不能保证这一点如果您改为在计时器触发时捕获系统时间,即使事件触发之间的时间是零星的,它也会计算出正确的时间。