DataBinding and iNotifyPropertyChanged in Xamarin

本文关键字:Xamarin in iNotifyPropertyChanged and DataBinding | 更新日期: 2023-09-27 18:14:57

我目前正在使用Xamarin Forms制作应用程序。这个应用程序将首先调用一个REST服务来检索数据并显示它们,然后将这些数据存储到SQLite数据库中。我有一个更新按钮,如果我点击它,它会提示REST服务再次检索新数据并替换旧数据,而应用程序正在运行。我试图实现INotifyPropertyChanged,但值只是不会为我改变。我错过了什么与我的代码下面?谢谢!

命脉对象:

public class Vitals
{
    public string Height { get; set; }
    public string ID { get; set; }
    public string Weight { get; set; }
}
更新方法:

async void OnUpdate(object sender, EventArgs e)
    {
        string tempUser = globalPatient.Username;
        string tempPin = globalPatient.PIN;
        patUpdate = patientManager.GetPatientByUsername (tempUser, tempPin).Result;
        App.PatientDB.DeletePatient(tempID);
        App.PatientDB.AddNewPatient (patUpdate, tempPin);
        DisplayAlert ("Updated", "Your information has been updated!", "OK");
    }

VitalsViewModal:

    public class VitalsViewModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public VitalsViewModel (Patient patient)
    {
        vitals = patient.Vitals;
    }
    private List<Vitals> _vitals;
    public List<Vitals> vitals { 
        get {return _vitals; }
        set {
            if (_vitals != value) {
                _vitals = value;
                OnPropertyChanged ("vitals");
            }
        }
    }
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }
}

VitalsView

public partial class VitalsView : ContentPage, INotifyPropertyChanged
{
    PatientManager patientManager = new PatientManager ();
    Patient globalPatient;
    public event PropertyChangedEventHandler PropertyChanged;
    public VitalsView (Patient patientZero)
    {
        InitializeComponent ();
        BindingContext = new VitalsViewModel (patientZero);
    }
 }

Xaml

<ListView x:Name="Vitals" ItemsSource="{Binding vitals}" RowHeight="80" BackgroundColor="Transparent">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.View>
                        <StackLayout Orientation="Vertical" Spacing="0" Padding="15">
                            <Grid>
                                <Label Font="17" Text="{Binding Height} " FontAttributes="Bold" TextColor="#449BC4" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" />
                                <Label Font="14" Text="{Binding Weight, StringFormat='Weight: {0}'}" FontAttributes="Bold"  Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" />
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="30" />
                                    <ColumnDefinition Width="2*" />
                                    <ColumnDefinition Width="2*" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                            </Grid>
                        </StackLayout>
                    </ViewCell.View>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

DataBinding and iNotifyPropertyChanged in Xamarin

要在Xaml中更改vitals,必须用新列表替换List<vitals整个列表。

即使病人改变了,它的生命体征从更新中是新的,你已经绑定了一个孤儿patient.vitals,其patient引用仍然有效。因此没有更改

需要将vitals的引用从旧的更改为新的。

我的建议是:

async void OnUpdate(object sender, EventArgs e)
{
    string tempUser = globalPatient.Username;
    string tempPin = globalPatient.PIN;
    patUpdate = patientManager.GetPatientByUsername (tempUser, tempPin).Result;
    App.PatientDB.DeletePatient(tempID);
    App.PatientDB.AddNewPatient (patUpdate, tempPin);
    MyCurrenViewModel.vitals = patUpdate.Vitals; // Replace old vitals
    DisplayAlert ("Updated", "Your information has been updated!", "OK");
}
在上面的例子中,我将在页面上创建一个名为MyCurrentViewModel的属性,当分配数据上下文时,我将使用
public partial class VitalsView : ContentPage, INotifyPropertyChanged
{
    VitalsViewModel MyCurrentViewModel { get; set; }
    PatientManager patientManager = new PatientManager ();
    PatientDemo globalPatient;
    public event PropertyChangedEventHandler PropertyChanged;
    public VitalsView (Patient patientZero)
    {
    InitializeComponent ();
    //BindingContext = new VitalsViewModel (patientZero);
      BindingContext = MyCurrentViewModel = new VitalsViewModel (patientZero);
    }
 }

代码复查其他错误

  • OnUpdateasync,这很好,但它从来没有awaits任何方法调用;因此,对它的所有调用本质上是同步的,并阻塞GUI线程等待结果。永远不要阻塞gui线程,否则应用程序会被冻结。

作为一个选项,你可以使用ObservableCollection来代替List。