2017-10-08 15 views
0

Veuillez aider: J'ai implémenté le design MVVM sur une application simple utilisant Xamarin. J'ai un Model (User) et un ViewModel (UserViewModel). S'il vous plaît noter que cette application est ma première application Xamarin/MVVM et que je suis nouveau à cela.MVVM INotifyPropertyChanged ne fonctionne pas

Le problème que j'ai est que l'ajout ou la suppression d'un utilisateur, la vue ne met pas à jour. Lorsque j'ajoute ou supprime un utilisateur, je peux confirmer que la base de données est mise à jour, mais pas mon affichage.

S'il vous plaît voir mon code ci-dessous, qu'est-ce que je manque?

Modèle utilisateur:

public class User 
{ 
    public int Id { get; set; } 
    public string Username { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public bool IsActive { get; set; } 

    public List<Role> RolesList { get; set; } 
} 

code UserViewModel:

public class UsersViewModel : INotifyPropertyChanged 
     { 
     private UserServices UserServ { get; set; } 

     public User UserSelected { get; set; } 

     private ObservableCollection<User> userList; 
     public ObservableCollection<User> UserList 
     { 
      get 
      { 
       return userList; 
      } 
      set 
      { 
       if (userList != value) 
       { 
        userList = value; 
        NotifyPropertyChanged(); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     public UsersViewModel() 
     { 
      UserServ = new UserServices(); 
      UsersLoadAsync(); 
     } 

     public async void UsersLoadAsync() 
     { 
      UserList = await UserServ.UsersGetAsync(); 
     } 
    } 

code service d'aide de l'utilisateur (surabondante)

public class UserServices 
    { 

     public async Task<ObservableCollection<User>> UsersGetAsync() 
     { 
      ObservableCollection<User> UserList = await App.UserService.GetAsync(); 

      return UserList; 
     } 

     public async Task<bool> UsersAddAsync(User user) 
     { 
      bool success = await App.UserService.PostAsync(user); 
      return success; 
     } 

     public async Task<bool> UsersRemoveAsync(User user) 
     { 
      bool success = await App.UserService.DeleteAsync(user.Id, user); 
      return success; 
     } 

    } 

Afficher le code 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:local="clr-namespace:PB_Logbook" 
      x:Class="PB_Logbook.MainPage" 
      xmlns:ViewModels="clr-namespace:PB_Logbook.ViewModels;assembly:PB_Logbook"> 

    <ContentPage.BindingContext> 
     <ViewModels:UsersViewModel/> 
    </ContentPage.BindingContext> 
    <StackLayout> 
     <ListView ItemsSource="{Binding UserList, Mode=TwoWay}" HasUnevenRows="True" ItemSelected="Item_SelectedAsync" IsPullToRefreshEnabled="True"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <ViewCell> 
        <StackLayout Orientation="Vertical" Padding="12,6"> 
         <Label Text="{Binding Username}" FontSize="24"/> 
         <Label Text="{Binding FirstName}" FontSize="18" Opacity="0.6"/> 
         <Label Text="{Binding LastName}" FontSize="18" Opacity="0.6"/> 
        </StackLayout> 
       </ViewCell> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
    <Button Text="Add" Clicked="AddButton_ClickedAsync"></Button> 
     <Button Text="Remove" Clicked="RemoveButton_ClickedAsync"></Button> 
    </StackLayout> 


</ContentPage> 

Afficher le code derrière:

public partial class MainPage : ContentPage 
    { 
     private UserServices UserServices { get; set; } 
     private UsersViewModel UsersVM { get; set; } 


     public MainPage() 
     { 
      InitializeComponent(); 
      UserServices = new UserServices(); 
      UsersVM = new UsersViewModel(); 
     } 

     private async void AddButton_ClickedAsync(object sender, EventArgs e) 
     { 
      await AddUserAsync(); 
     } 

     private async void RemoveButton_ClickedAsync(object sender, EventArgs e) 
     { 
      await RemoveUserAsync(); 
     } 

     private async void Item_SelectedAsync(object sender, EventArgs e) 
     { 
      UsersVM.UserSelected = ((User)((ListView)sender).SelectedItem); 

     } 

     private async void Pull_RefreshAsync(object sender, EventArgs e) 
     { 
      //UsersVM.UsersLoadAsync(); 
     } 

     private async Task AddUserAsync() 
     { 
      Random rnd = new Random(); 
      int rndNumber = rnd.Next(1, 100); 

      User user = new User() 
      { 
       Username = "User " + rndNumber, 
       FirstName = "Firstname " + rndNumber, 
       LastName = "Surname " + rndNumber, 
       IsActive = true 
      }; 

      bool success = await UserServices.UsersAddAsync(user); 

      if (success) 
      { 
       if (!UsersVM.UserList.Contains(user)) 
        UsersVM.UserList.Add(user); 
      } 
     } 

     private async Task RemoveUserAsync() 
     { 
      bool success = await UserServices.UsersRemoveAsync(UsersVM.UserSelected); 

      if (success) 
      { 
       if (UsersVM.UserList.Contains(UsersVM.UserSelected)) 
        UsersVM.UserList.Remove(UsersVM.UserSelected); 
      } 
     } 
    } 

La question est à l'ajout/suppression des utilisateurs qui ne mettent pas à jour à mon avis.

Merci.

+1

'Replace Liste <>' et 'votre implémentation INotifyPropertyChanged' avec' ObservableCollection <> '. – jsanalytics

+0

Merci pour la réponse, @jstreet. J'ai remplacé List <> avec ObservableCollection <> mais ne fonctionne toujours pas. Tout autre conseil? –

+0

Je vais regarder de plus près dès que j'ai une chance. – jsanalytics

Répondre

2

Si vous êtes nouveau Xamarin MVVM, ce lien vous aidera à comprendre les bases de MVVM dans Xamarin Forms

https://deanilvincent.github.io/2017/06/03/basic-understanding-of-mvvm-and-databinding-in-xamarin-forms/

Je suggère aussi, s'il vous plaît Diminuez votre derrière les codes et juste mettre en œuvre tout y compris les commandes dans votre ViewModel.

Vous avez écrit que vos codes fonctionnent lors de la sauvegarde et de la mise à jour, mais ne reflètent pas correctement l'affichage? Vous devriez mettre votre méthode en récupérant la liste juste après votre commande de sauvegarde.

Comme dans votre XAML

<Button Text="Save" Command="{Binding SaveCommand}"/> 

Dans votre ViewModel, vous devez utiliser la commande de Xamarin

public Command SaveCommand{ 
    get{ 
     return new Command(async()=>{ 
      // your command save here 
      // then put your method for fetching the updated list: your UsersLoadAsync(); 
     }); 
    } 
} 

Si vous êtes nouveau MVVM, vous pouvez également vérifier link. Il utilise Xamarin MVVM. Lorsque vous avez terminé, vous aurez application simple météo avec de simples implémentations MVVM

J'espère que vous aide

+0

Merci pour le post. J'ai suivi votre conseil et déplacé toute ma logique et mes commandes vers le ViewModel. J'ai également essayé de recharger la liste après l'enregistrement, mais il n'actualise toujours pas la vue. –