尝试不断更新视图中的字符串。使用MVVM,所以我已经建立了我的视图模型,并设置了一个计时器,以不断更新字符串与当前时间。
计时器位于视图模型的构造函数中,而构造函数在视图的代码隐藏的构造函数中调用。
由于某种原因,每当我在计时器中的方法中设置字符串属性时,它不会更新视图?我在timer方法中有一个控制台写行,它可以按预期工作。为什么视图没有得到更新后的字符串?
视图模型
public class MainViewModel
{
//
TimeIntervals Interval = TimeIntervals.Seconds;
int DurationOfInterval = 1;
public MainViewModel()
{
TimeLeft = "2023.5.18";
DateTime LastRecordedTime = DateTime.MinValue;
Device.StartTimer(TimeSpan.FromSeconds(3), () =>
{
DateTime CurrentTime = DateTime.Now;
Console.WriteLine($"time has passed {LastRecordedTime.ToString("dd/MM/yyyy |HH:mm:ss")}");
TimeLeft = CurrentTime.ToString();
return true;
});
}
string timeLeft;
public string TimeLeft
{
set { SetProperty(ref timeLeft, value); }
get { return timeLeft; }
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string PropertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(PropertyName);
return true;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string PropertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
查看
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DeathClock.Main"
x:Class="DeathClock.MainPage">
<ContentPage.BindingContext>
<local:MainViewModel/>
</ContentPage.BindingContext>
<StackLayout Background="black">
<Grid ColumnDefinitions="3*,1*" BackgroundColor="Black" >
<Grid Grid.Column="0" RowDefinitions = "2*,400,1*" Padding="5" >
<Grid Grid.Column="0" ColumnDefinitions="50,200" >
<Button Grid.Column="0" Text="Config" Command="{Binding goToSettings}"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" RowDefinitions="2*,2*" ColumnDefinitions="2*,2*,2*" Padding="5">
<Label Grid.Column="0" Grid.Row="0" VerticalOptions="CenterAndExpand" FontSize="Title" Text="{Binding TimeSpent}" BackgroundColor="Purple"/>
<Label Grid.Column="0" Grid.Row="1" VerticalOptions="CenterAndExpand" FontSize="Title" Text="{Binding TimeLeft}" BackgroundColor="Purple"/>
</Grid>
</Grid>
<StackLayout Grid.Column="1" Rotation="-90" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" ScaleX="5" Background="black" >
<ProgressBar ProgressColor="Bisque" Progress="{Binding LifeProgress}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" ScaleY="20" ></ProgressBar>
</StackLayout>
</Grid>
</StackLayout>
</ContentPage>
代码隐藏
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MainViewModel ViewModel = new MainViewModel();
}
}
1条答案
按热度按时间yqlxgs2m1#
仍然有趣的是,视图如何在没有实现INotifyPropertyChanged的情况下在计时器之外更新。
为此,您还需要为视图模型实现接口
INotifyPropertyChanged
。从官方文档ViewModels和Property-Change Notifications中,我们可以发现:
ViewModel是数据绑定源。ViewModel没有定义可绑定的属性,但是它实现了一个通知机制,允许在属性值更改时通知绑定基础结构。此通知机制是INotifyPropertyChanged接口,它定义了一个名为PropertyChanged的事件。实现此接口的类通常在其某个公共属性更改值时激发事件。
因此,您需要实现接口
INotifyPropertyChanged
,并为您希望在更改这些属性的值时自动更新UI的属性调用函数OnPropertyChanged
。例如:
此外,您可以根据需要随时更改属性的值,只要为您的视图模型实现接口
INotifyPropertyChanged
,并为您的属性调用OnPropertyChanged
,UI就会自动更新。根据您的代码,我向视图模型添加了一个命令,并绑定到按钮以更改属性
TimeLeft
和TimeSpent
的值,然后UI将自行更新。方法
updateTimeMethod
你可以在这里看到完整的代码:
主页.xaml
注意事项:
由于您已经在
Yourpage.xaml
上为页面设置了MainViewModel
,因此不需要在Yourpage.xaml.cs
上再次设置,因此请删除代码: