Привязка DispatcherTimer не показывает его значение в представлении - PullRequest
0 голосов
/ 05 мая 2019

В классе UserInteractiton я создал экземпляр класса TestTimer, в котором находится таймер. Я запускаю его и хочу отобразить значение этого таймера в View, но по какой-то причине ничего не отображается.

View

<Grid>
    <TextBlock Name="textTimeMiddle" TextWrapping="Wrap"
       Text="{Binding TestTimer.TimeFormat, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>

VievModel

public class UserInteractiton : INotifyPropertyChanged
{
    public UserInteractiton()
    {
        TestTimer = new TestTimer();
    }

    public TestTimer TestTimer { get; private set; }
}

Модель

public class TestTimer : INotifyPropertyChanged
    {
        private string timeFormat;
        public string TimeFormat
        {
            get { return timeFormat; }
            set
            {
                timeFormat = value;
                OnPropertyChanged();
            }
        }

        public TestTimer()
        {
            StartTimer();
        }

        public void StartTimer()
        {
            Timer = new DispatcherTimer();
            Timer.Interval = new TimeSpan(0, 0, 1);
            Timer.Tick += TimerTick;
            Timer.Start();
        }

        private async void TimerTick(object sender, EventArgs e)
        {
            await Task.Run(() => TimerCycle());
        }

        private void TimerCycle()
        {
            for (;;)
            {
                if (Seconds > 59)
                {
                    Seconds = 0;
                    Minutes++;

                    if (Minutes > 59)
                    {
                        Minutes = 0;
                        Hours++;

                        if (Hours > 23)
                            Hours = 0;
                    }
                }
                Seconds++;

                timeFormat = string.Format("{0:00}:{1:00}:{2:00}",
                    Hours, Minutes, Seconds);
                Thread.Sleep(200);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }
    }

1 Ответ

2 голосов
/ 05 мая 2019

Вы должны вызвать событие INotifyPropertyChanged.PropertyChanged, чтобы уведомить представление о том, что некоторые свойства вашей модели представления были изменены.Базовая реализация INotifyPropertyChanged подразумевает, что у вас есть метод для вызова этого события:

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

И вы должны вызвать этот метод из установщика свойства, чтобы привязка работала правильно:

    private string _timeFormat;

    public string TimeFormat
    {
        get { return _timeFormat; }
        private set
        {
            _timeFormat = value;
            OnPropertyChanged(nameof(TimeFormat));
        }
    }

Если вы отметите параметр propertyName параметром [CallerMemberName], вы можете игнорировать передачу аргумента методу OnPropertyChanged:

    public string TimeFormat
    {
        get { return _timeFormat; }
        private set
        {
            _timeFormat = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

Полный код вашего TestTimer класса ниже:

    public class TestTimer : INotifyPropertyChanged
    {
        private string _timeFormat;
        public int Minutes { get; private set; }
        public int Seconds { get; private set; }
        public int Hours { get; private set; }
        public DispatcherTimer Timer { get; private set; }
        public string TimeFormat
        {
            get { return _timeFormat; }
            private set
            {
                _timeFormat = value;
                OnPropertyChanged(nameof(TimeFormat));
            }
        }

        public TestTimer()
        {
            StartTimer();
        }

        public void StartTimer()
        {
            Timer = new DispatcherTimer();
            Timer.Interval = new TimeSpan(0, 0, 1);
            Timer.Tick += TimerTick;
            Timer.Start();
        }

        private async void TimerTick(object sender, EventArgs e)
        {
            await Task.Run(() => TimerCycle());
        }

        private void TimerCycle()
        {
            for (; ; )
            {
                if (Seconds > 59)
                {
                    Seconds = 0;
                    Minutes++;

                    if (Minutes > 59)
                    {
                        Minutes = 0;
                        Hours++;

                        if (Hours > 23)
                            Hours = 0;
                    }
                }
                Seconds++;

                TimeFormat = string.Format("{0:00}:{1:00}:{2:00}",
                    Hours, Minutes, Seconds);
                Thread.Sleep(200);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...