I am making a fitness app so I need a timer.I have done this in code-behind:
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();
}
}
And then for the UI, I made a label and bound its text property to my Time property:
<Label BindingContext ="{x:Reference this}"
Text="{Binding Time}"/>
//"this" is a reference to my class
When I start the app, the timer remains 30. I know that "seconds" is for sure decreasing, so there must be a problem with the binding.I know I could've just updated the text property of the label inside OneSecondPassed , but I'd like to learn more about data binding.Help?
CodePudding user response:
As Jason said, implementing the INotifyPropertyChanged
interface is a good choice.
For your better understanding, I wrote a runnable project that meets your requirements for your reference.
Here is the xaml code:
<StackLayout>
<Label Text="{Binding DateTime}"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</StackLayout>
Here is the cs code:
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
int dateTime;
public event PropertyChangedEventHandler PropertyChanged;
public MainPage()
{
InitializeComponent();
this.DateTime = 30;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
if (DateTime > 0)
{
DateTime--;
}
return true;
});
BindingContext = this;
}
public int DateTime
{
set
{
if (dateTime != value)
{
dateTime = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));
}
}
}
get
{
return dateTime;
}
}
}