首先,我不存在线程不更新值的一般问题,它只是一个值。
我创建了一个由进度条组成的时钟。时钟背后的“引擎”是第二个线程:
Thread clock = new Thread(UpdateRelative);
clock.IsBackground = true;
clock.Start();
在我进入UpdateRelative()
-方法之前,这是我的Xaml时钟:
<Grid>
<Grid.DataContext>
<vm:TimerVM/>
</Grid.DataContext>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,10,10,10">
<Border BorderBrush="Gray" BorderThickness="1">
<Label Content="Progress Bar Timer" FontFamily="Bold" FontSize="45" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,0,0,20"/>
</Border>
<StackPanel>
<Label Content="Seconds in this Minute:"/>
<Grid Width="400" Height="25">
<ProgressBar Value="{Binding SecondsInMinute}" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="{Binding SecondsInMinute, StringFormat=N0}"/><Run Text="%"/>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel>
<Label Content="Minutes in this hour:"/>
<Grid Width="400" Height="25">
<ProgressBar Value="{Binding MinutesInHour}" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="{Binding MinutesInHour, StringFormat=N0}"/><Run Text="%"/>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel>
<Label Content="Hours in this day:"/>
<Grid Width="400" Height="25">
<ProgressBar Value="{Binding HoursInDay}" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="{Binding HoursInDay, StringFormat=N0}"/><Run Text="%"/>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel Margin="0,50,0,0">
<Label Content="Time until timer finished:"/>
</StackPanel>
<Grid Width="400" Height="25">
<ProgressBar Value="{Binding TimerInPercent}" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="{Binding TimerInPercent, StringFormat=N0}"/><Run Text="%"/>
</TextBlock>
</Grid>
</StackPanel>
</Grid>
在程序中看起来像这样:
现在是方法:这由我的第二个线程执行:
private void UpdateRelative()
{
bool x = false;
while (true)
{
DateTime time = DateTime.Now;
SecondsInMinute = time.Second / 0.6;
MinutesInHour = time.Minute / 0.6;
HoursInDay = time.Hour / 0.24;
if (timerReady)
{
if (!x)
{
//TimerEnd is the current time plus 2 minutes
TimerEnd = new DateTime(TimerYear, TimerMonth, TimerDay, TimerHour, TimerMin, TimerSec);
TimerInPercent = 0;
x = true;
Start = DateTime.Now;
}
DateTime now = DateTime.Now;
DateTime end = TimerEnd;
var endTimeSpan = now - Start;
TimeSpan entireTime = end - Start;
TimerInPercent = (100 / entireTime.TotalSeconds) * endTimeSpan.TotalSeconds;
}
Thread.Sleep(timeout);
}
}
一般的问题是TimerInPercent
。我将其放在if语句中,因为在按下按钮后,它应该只开始更新。此刻,计时器的“结束时间”在启动程序2分钟后设置。虽然每个值本身都会更新(SecondsInMinute
,MinutesInHour
,HoursInDay
和TimerInPercent
),但在GUI中也仅更新前三个。
例如,我在8:30启动程序。计时器现在设置为8:32。现在,我按下“确定”按钮。调试时,我可以看到值TimerInPercent
正在更改其值。但是,尽管有其他值,但该值不会在GUI中更新。
当我删除if语句并从头开始更新值时,它将在GUI中更新。
我的问题是:如果不是从头开始更新值,而是稍后(在我按下按钮之后),线程为什么不更新GUI中的值?
嗯,它既与绑定无关,也与WPF都不相关,与该行有关:
TimerInPercent = (100 / entireTime.TotalSeconds) * endTimeSpan.TotalSeconds
您正在尝试将整数100除以更大的值,这将导致0。
您可以用(100.0 / entireTime.TotalSeconds)
尝试一下
还请确保将TimerInPercent
定义为double