web-dev-qa-db-fra.com

Comment implémenter INotifyPropertyChanged dans Xamarin.Forms

J'implémente un panier dans Xamarin.Forms. Dans ma page de panier, il y a un ListView avec des données. Chacune des cellules contient un bouton pour sélectionner le nombre d'élément et le montant . Dans la vue du panier, il y a une étiquette de total général.

Mon problème est que le grand total n'est pas mis à jour pendant que le sélecteur de numéro change. La méthode de calcul est appelée sur l'élément ajoutant la cellule de vue. Je sais que je dois implémenter INotifyProperty pour cela, mais je ne sais pas comment le faire.

J'ai un modèle de vue de base qui hérite de INotifyProperty qui contient un événement.

 public class BaseViewModel : INotifyPropertyChanged
{
    private double  _price;
    public double Price
    {
        get 
        { 
            return _price; 
        }
        set 
        { 
            _price = value;
            OnPropertyChanged("Price");}
        } 

 protected virtual void OnPropertyChanged(string propertyName)
 {
     if (PropertyChanged != null)
     {
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     }
 }

Voir le modèle

    public BaseViewModel()
    {
        App.Instance.ViewModel = this;
        TempList = TempList ?? new ObservableCollection<cm_items>();
        this.Title = AppResources.AppResource.Cart_menu_title;
        this.Price = CartCell.price;
    }
11
user4318551

En tant que méthodologie de conception, il est préférable d'implémenter MVVM en tant que sous-classe et de l'implémenter dans votre ViewModel.

Exemple d'implémentation:

public class ObservableProperty : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Je suggère également fortement d'implémenter ICommand comme une structure de dictionnaire comme:

public abstract class ViewModelBase : ObservableProperty
{
    public Dictionary<string,ICommand> Commands { get; protected set; }

    public ViewModelBase()
    {
        Commands = new Dictionary<string,ICommand>();
    }
}

Donc, toutes les tâches de votre ViewModel héritent simplement de la classe ViewModelBase et l'utilisent

class LoginViewModel : ViewModelBase
{
    #region fields
    string userName;
    string password;
    #endregion

    #region properties
    public string UserName 
    {
         get {return userName;}
        set 
        {
            userName = value;
            OnPropertyChanged("UserName");
        }
     }

    public string Password 
    {
        get{return password;}
        set
        {
            password = value;
            OnPropertyChanged("Password");
        }
    }
    #endregion

    #region ctor
    public LoginViewModel()
    {
        //Add Commands
        Commands.Add("Login", new Command(CmdLogin));
    }
    #endregion


    #region UI methods

    private void CmdLogin()
    {
        // do your login jobs here
    }
    #endregion
}

Enfin: Xaml Usage:

<Entry Placeholder="Username"  Text="{Binding UserName}"/>
<Entry Placeholder="Password" Text="{Binding Password}" IsPassword="True"/>
<Button Text="Login" Command="{Binding Commands[Login]}"/>
16
eakgul

Par exemple, essayez ce modèle de vue:

public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetPropertyValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (value == null ? field != null : !value.Equals(field))
        {
            field = value;

            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
            return true;
        }
        return false;
    }
}

et dans les classes héritées, utilisez-le comme ceci:

    private int myProperty;
    public int MyProperty
    {
        get { return this.myProperty; }
        set { this.SetPropertyValue(ref this.myProperty, value); }
    }
1
Jauhenka

Lorsque j'ai commencé à coder Xamarin, le MVVM était un peu déroutant jusqu'à ce que je découvre que le PropertyChangedEvent sur le ViewModel a déclenché un signal vers la vue (ContentPage) et mis à jour le Label/textbox/etc.

Pour ceux qui recherchent le "dernier et le meilleur" ... Voici un code révisé:

private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

et sur votre propriété Setter:

public string SomeProperty
{
    get { return _somProperty; }
    set
    {
       _someProperty= value;
            OnPropertyChanged();
        }
    }
}

Agréable? Non? Vous évite d'avoir à passer le nom de la propriété à chaque fois!

0
Mark Rooney