Прежде всего, у меня нет общих проблем с тем, что мой поток не обновляет значения, это всего лишь одно значение.
Я создал часы, которые сделаны из индикаторов прогресса. «Двигатель» за часами - это вторая нить:
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.
Это TimerInPercent:
public double TimerInPercent
{
get => _timerInPercent;
set
{
_timerInPercent = value;
OnPropertyChanged();
}
}
Например, я запускаю программу в 8:30. Таймер теперь установлен на 8:32. Теперь я нажимаю кнопку «ОК». Во время отладки я вижу, что значение TimerInPercent
меняет свое значение. Но, несмотря на другие значения, это значение не обновляется в GUI.
. Когда я удаляю оператор if и обновляю значение с начала, оно обновляется в GUI.
Мой вопрос: почему поток не обновляет значение в GUI, если значение обновляется не с начала, а позже (после того, как я нажал кнопку)