在我的项目 Xamarin 中实施 INotifyPropertyChanged

Implementing INotifyPropertyChanged in my project Xamarin

所以我有一个名为 "Objets" 的模型 class 并且我想创建一个 ViewModel 以便我可以跟踪我的模型 class 参数之一发生的变化即 "nbr_objet"。 我应该怎么办 ? 这是我到目前为止所做的,请纠正我。

型号Class:


public class Objets
    {
    public string Designation { get; set; }
    public string Description { get; set; }
    public float Prix { get; set; }
    public int nbr_objet { get; set; }
    public Objets(string Designation, string Description, float Prix, int nbr_objet)
    {
        this.Designation = Designation;
        this.Description = Description;
        this.Prix = Prix;
        this.nbr_objet= nbr_objet;
    }
    }

我明显有问题的ModelViewBase


class ViewModelBase : INotifyPropertyChanged
    {
    public Objets ObjetVM { get; set; }
    public int nbr_objet 
    {
        get { return ObjetVM.nbr_objet; }
        set
        {
            ObjetVM.nbr_objet = value;
            OnPropertyChanged(nameof(ObjetVM.nbr_objet));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyname)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
    }
}

这是我的 MainPage.xaml.cs,我在其中创建了多个 "Objets"


    public MenuPage()
    {
        InitializeComponent();
        this.BindingContext = new ViewModelBase();
    }

您需要在要跟踪更改的任何对象上实施 INotifyPropertyChanged。现在您只跟踪视图模型上的更改,因此您还需要在 Objets class 上添加 INotifyPropertyChanged,以及 class 中的每个 属性 和 getters/setters 使用 OnPropertyChanged 就像您在视图模型中所做的那样。

public class Objets: INotifyPropertyChanged

这是运行截图。

您可以在 model.

中按照以下格式实现它
 public  class MyObjets : INotifyPropertyChanged
{
   // public string Designation { get; set; }
  //  public string Description { get; set; }
 //   public float Prix { get; set; }
 //   public int nbr_objet { get; set; }


    int _nbr_objet;
    public int Nbr_objet
    {
        get
        {
            return _nbr_objet;
        }

        set
        {
            if (_nbr_objet != value)
            {
                _nbr_objet = value;
                OnPropertyChanged("Nbr_objet");

            }
        }

    }

    float _prix;
    public float Prix
    {
        get
        {
            return _prix;
        }

        set
        {
            if (_prix != value)
            {
                _prix = value;
                OnPropertyChanged("Prix");

            }
        }

    }

    string _designation;
    public string Designation
    {
        get
        {
            return _designation;
        }

        set
        {
            if (_designation != value)
            {
                _designation = value;
                OnPropertyChanged("Designation");

            }
        }

    }

    string _description;
    public string Description
    {
        get
        {
            return _description;
        }

        set
        {
            if (_description != value)
            {
                _description = value;
                OnPropertyChanged("Description");

            }
        }

    }


    public MyObjets(string Designation, string Description, float Prix, int nbr_objet)
    {
        this._designation = Designation;
        this._description = Description;
        this._prix = Prix;
        this._nbr_objet = nbr_objet;
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
 }

然后是布局。

   <StackLayout>
    <!-- Place new controls here -->
    <Label Text="{Binding Designation}" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Label Text="{Binding Description}" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Label Text="{Binding Prix}" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Label Text="{Binding Nbr_objet}" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
  </StackLayout>

这是布局后端代码。

  public MainPage()
    {
        InitializeComponent();
        BindingContext = new MyObjets("xxxx","cccc",1.22f,11);
    }

这里是我的MVVM with Listview demo,你也可以参考一下。 https://github.com/851265601/MVVMListview

如果回复有帮助,请不要忘记标记为答案。

======================更新============ ============

您想达到GIF动图这样的效果吗?

这是你的模型

  public  class MyObjets 
{
    public string Designation { get; set; }
    public string Description { get; set; }
    public float Prix { get; set; }
    public int nbr_objet { get; set; }

    public MyObjets(string Designation, string Description, float Prix, int nbr_objet)
    {
        this.Designation = Designation;
        this.Description = Description;
        this.Prix = Prix;
        this.nbr_objet = nbr_objet;
    }

}

这里是ViewModelBase

 public class ViewModelBase: INotifyPropertyChanged
{
    public ViewModelBase()
    {

        ObjetVM = new MyObjets("ccc","xxx",1.2f,123);
    }
public MyObjets ObjetVM { get; set; }
    public int nbr_objet
    {
        get { return ObjetVM.nbr_objet; }
        set
        {
            ObjetVM.nbr_objet = value;
            OnPropertyChanged(nameof(ObjetVM.nbr_objet));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyname)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}

}

此处为底层代码布局。

 <StackLayout>

    <Label Text="{Binding nbr_objet}" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />

    <Button Text="change the value" Clicked="Button_Clicked"></Button>
</StackLayout>

这里是布局背景代码

   public partial class MainPage : ContentPage
{
    ViewModelBase viewModelBase;
    public MainPage()
    {
        InitializeComponent();


        viewModelBase =  new ViewModelBase();
        BindingContext = viewModelBase;
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        viewModelBase.nbr_objet = 111;
    }
}

当您更改 属性 "nbr_objet" 时,您提出 ObjetVM 中的 属性 已更改,但这不是您的 bindingContext - 您的 bindingContext 是 ViewModelBase。

所以宁愿重写它:

private int nbr_object;

public int Nbr_objet_property
{
    get { return nbr_objet; }
    set
    {
        nbr_objet = value;
        OnPropertyChanged(nameof(Nbr_objet_property));
    }
}

然后每次你 cahnge "Nbr_objet_property" 它应该更新你绑定的任何东西。

此外,"ObjetVM" 不是 viewModel,因为它没有实现 INotifyPropertyChanged 逻辑。

希望它有意义? :)