es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Temporizador Xamarin no se actualiza.

Estoy haciendo una aplicación de fitness, así que necesito un temporizador. He hecho esto en el código detrás:

public partial class Timer : ContentView
    {
        private int seconds = 30;
        private System.Timers.Timer timer;
        public Timer()
        {
            InitializeComponent();
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.AutoReset = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OneSecondPassed);
            timer.Enabled = true;
        }
        private void OneSecondPassed(object source, System.Timers.ElapsedEventArgs e)
        {
            seconds--;
        }
        public string Time
        {
            get => seconds.ToString();
        }
    }

Y luego para la interfaz de usuario, hice una etiqueta y vinculé su propiedad de texto a mi propiedad Time:

<label bindingcontext="{x:Reference this}" text="{Binding Time}"></label>
// "this" es una referencia a mi clase

Cuando inicio la aplicación, el temporizador sigue siendo 30. Sé que “seconds” está disminuyendo, así que debe haber un problema con la vinculación de datos. Sé que podría haber actualizado la propiedad de texto de la etiqueta dentro de OneSecondPassed, pero me gustaría aprender más sobre la vinculación de datos. ¿Ayuda?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema puede estar en la implementación de la interfaz INotifyPropertyChanged, que es necesaria para que la vinculación de datos funcione correctamente.

    Para solucionar este problema, puede modificar la clase Timer para implementar la interfaz INotifyPropertyChanged y disparar el evento PropertyChanged en el setter de la propiedad Time:

    public partial class Timer : ContentView, INotifyPropertyChanged
    {
        private int seconds = 30;
        private System.Timers.Timer timer;
    
        public Timer()
        {
            InitializeComponent();
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.AutoReset = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OneSecondPassed);
            timer.Enabled = true;
        }
    
        private void OneSecondPassed(object source, System.Timers.ElapsedEventArgs e)
        {
            Seconds--;
        }
    
        public int Seconds
        {
            get => seconds;
            set
            {
                if (seconds == value)
                {
                    return;
                }
                seconds = value;
                OnPropertyChanged(nameof(Time));
            }
        }
    
        public string Time
        {
            get => Seconds.ToString();
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Luego, en la interfaz de usuario, puede modificar la etiqueta para usar el modo de enlace OneWay, lo que significa que la etiqueta solo mostrará el valor de la propiedad vinculada y no lo actualizará:

    <label bindingcontext="{x:Reference this}" text="{Binding Time, Mode=OneWay}"></label>
    

    Con estos cambios, la etiqueta debería actualizarse para mostrar el valor decreciente del temporizador.

Comments are closed.