[英]Xamarin.Forms Binding only updating ViewModel property with default values
[英]ViewModel not updating form (Xamarin.Forms)
我正在尝试使用 ViewModel 来更新 XAML 页面上的计数器,但无法弄清楚我做错了什么......
itemCount 的初始值显示良好,但每次递增后都不会更新。
这是 XAML 源代码:
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
xmlns:local="clr-namespace:XamarinFormsTest01"
mc:Ignorable="d"
x:Class="XamarinFormsTest01.MainPage">
<StackLayout>
<Label x:Name="lblMain" Text="{Binding ItemCount}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" >
<Label.BindingContext>
<local:ItemCountViewModel />
</Label.BindingContext>
</Label>
<Button x:Name="BtnStart" Text="start" Pressed="BtnStart_Pressed" />
<Button x:Name="BtnStop" Text="stop" Pressed="BtnStop_Pressed" />
</StackLayout>
</ContentPage>
和 ViewModel 源代码:
public class ItemCountViewModel : INotifyPropertyChanged
{
private static ItemCountViewModel instance = new ItemCountViewModel();
public static ItemCountViewModel GetInstance()
{
return instance;
}
int itemCount;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public ItemCountViewModel()
{
itemCount = 0;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
itemCount++;
return true;
}
);
}
public int ItemCount
{
set
{
itemCount = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ItemCount"));
}
get
{
return itemCount;
}
}
}
从ItemCount.set
您正在提升PropertyChanged
,这是视图根据视图模型的状态更新所必需的。 否则视图将不得不轮询状态变化,这将浪费资源,尤其是在我们希望避免因过度使用处理器而耗尽电池的移动设备上。
无论如何,当你在做的时候直接设置itemCount
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
itemCount++;
return true;
}
ItemCount.set
永远不会被调用,因此PropertyChanged
永远不会被引发,并且视图没有机会确定视图模型改变了它的状态。 此外,我猜ItemCount
必须在 UI 主线程中设置,因此您必须通过Device.BeginInvokeOnMainThread
包装对ItemCount.set
的Device.BeginInvokeOnMainThread
( 请参阅文档)
将代码更改为
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
Device.BeginInvokeOnMainThread (() =>
{
ItemCount++;
});
return true;
}
并且视图应该更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.