【问题标题】:ViewModel not updating form (Xamarin.Forms)ViewModel 不更新表单 (Xamarin.Forms)
【发布时间】:2020-03-10 14:20:33
【问题描述】:

我正在尝试让 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;
        }
    }
}

【问题讨论】:

标签: c# android forms xamarin viewmodel


【解决方案1】:

您从ItemCount.set 提出PropertyChanged,这是根据视图模型的状态更新视图所必需的。否则视图必须轮询状态变化,这会浪费资源,尤其是在我们希望避免过度使用处理器耗尽电池的移动设备上。

无论如何,当你直接设置itemCount

Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
    itemCount++;
    return true;
}

ItemCount.set 永远不会被调用,因此PropertyChanged 永远不会被提升,并且视图没有机会确定视图模型改变了它的状态。此外,我猜ItemCount 必须在 UI 的主线程中设置,因此您必须通过 Device.BeginInvokeOnMainThread (see the documentation) 包装对 ItemCount.set 的调用

把代码改成

Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
    Device.BeginInvokeOnMainThread (() => 
    {
      ItemCount++;
    });
    return true;
}

并且视图应该更新。

【讨论】:

  • 我现在有另一个问题。在另一个页面(MainPage.xaml.cs)上,当我执行以下调用时,ItemCount 不会更新:ItemCountViewModel.GetInstance().ItemCount++;
  • @KotlinIsland 很抱歉,但我不明白你的意思。您是否希望 ItemCount 在页面之间持续存在?
  • 当我从 ViewModel 内部执行“ItemCount++”时,值会得到很好的更新。但是当我从 XAML 代码隐藏文件中增加 ItemCount 时,它不会更新...
  • @KotlinIsland 也许你应该通过添加相应的代码来提出另一个问题。
猜你喜欢
  • 1970-01-01
  • 2020-09-24
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多