2015-09-29 69 views
1

我目前正在使用Xamarin Forms製作應用程序。這個應用程序將首先調用REST服務來檢索數據並顯示它們,然後將這些數據存儲到SQLite數據庫中。我有一個更新按鈕,如果點擊它,它將再次提示REST服務檢索更新的數據,並在應用程序運行時替換舊數據。我試圖實現INotifyPropertyChanged,但值不會'改變我。我是否錯過了我的代碼?謝謝!Xamarin中的DataBinding和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> 
+0

在Update方法中,你在修改ViewModel嗎?你能告訴我們你是如何設置你的數據綁定? – Jason

+0

感謝您回覆@Jason!我剛剛添加了數據綁定部分。另外,我應該如何修改ViewModel? – Fayt

+0

你的綁定看起來是正確的。但是當你得到新數據時你需要更新你的ViewModel - 它不會自動發生。想必你會將vitals屬性設置爲新的數據集合。 – Jason

回答

1

對於vitals有在XAML的變化,一些必須用一個新的列表取代的List<vitals整個列表。

即使病人改變其要害是從更新新的,你已經綁定到一個孤立patient.vitalspatient基準仍然有效。 因此沒有變化

您需要特別將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頁面上,和財產分配DataContext的時候我都會有

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); 
    } 
} 

Code Review其他錯誤

  • OnUpdateasync這很好,但它從來沒有awaits任何方法調用;因此所有對它的調用都是同步的,並阻止GUI線程等待結果。永遠不要阻止gui線程,應用程序將顯示凍結。
+0

感謝您回覆@OmegaMan! 1.這只是舊代碼,應該被註釋掉。我重新編輯了第一頁。 2.謝謝指出!當我嘗試更新時,我注意到了應用程序的凍結;可能在未來做些什麼。 – Fayt

1

作爲選項,您可以使用ObservableCollection而不是List。

+0

我也嘗試這樣做,同時應用Fody.PropertyChange nudget。 – Fayt