WPF: Почему мой поток обновляет только некоторые значения - PullRequest
0 голосов
/ 30 апреля 2020

Прежде всего, у меня нет общих проблем с тем, что мой поток не обновляет значения, это всего лишь одно значение.

Я создал часы, которые сделаны из индикаторов прогресса. «Двигатель» за часами - это вторая нить:

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>

В Программа выглядит так:

enter image description here

Теперь к методу: это выполняется моим вторым потоком:

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, если значение обновляется не с начала, а позже (после того, как я нажал кнопку)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...