Xamarin Forms connect products with user accounts

88 Views Asked by At

I'm making a shopping app, it has account for the user, and when the user purchases a product, it should be added to a listview in his account. So I tried to put a static object of the User Class that has a list of Products, and whenever the user clicks the buying button, it should be added to the list. At the same time, the user.xaml is binding to the same object. But it doesn't work. What's the error in my method? Are there any better ideas to do this?

here's the static field in the App.xaml.cs file

 private IDataService _dataService;

 public static User TheUser;
 public App(IDataService dataService)
 {
     TheUser = new User();
     InitializeComponent();
     var unity = new UnityContainer();
     unity.RegisterType<IDataService, DataServices>();
     ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(unity));
     _dataService = dataService;
     MainPage = new NavigationPage(new MainPage());

 }

and here's the User.xaml.cs property

public User User
{
    get { return App.TheUser; }
    set
    { 
        if(App.TheUser!= null)
        App.TheUser = value;
    }

    //User class 
    public class User : Base //Base class implements INotifyPropertyChanged
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ObservableCollection<Product> Products = new ObservableCollection<Product>();
    }


  public class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Here's the User.Xaml file

<StackLayout>

    <AbsoluteLayout>
     <Image AbsoluteLayout.LayoutBounds="1 , 0 ,96 ,96" AbsoluteLayout.LayoutFlags="PositionProportional"/>
     <Label AbsoluteLayout.LayoutBounds="0 , 50 , 100 , 20" AbsoluteLayout.LayoutFlags="XProportional" Text="First Name"/>
     <Label AbsoluteLayout.LayoutBounds="0 , 100 , 100 , 20" AbsoluteLayout.LayoutFlags="XProportional" Text="Last Name"/>
 </AbsoluteLayout>

    <ListView x:Name="UserListView"
              SelectedItem="{Binding SelectedItemCommand}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>

                <StackLayout Spacing="3" FlowDirection="RightToLeft" >
                    <Image Source="{Binding ProductMainImage}" Aspect="AspectFill" Margin="3" HeightRequest="300" />

                    <Label Text="{Binding Name ,StringFormat=' الاسم : {0}'}"/>
                    <Label Text="{Binding Price ,StringFormat=' السعر : {0}'}"/>
                    <Label Text="{Binding Description ,StringFormat=' الوصف : {0}'}"/>
                </StackLayout>
                </ViewCell>

                </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>
1

There are 1 best solutions below

2
On

ok so the property notification doesn't happen automatically. You need to invoke that code to raise the event. This should takes care of the code, but without seeing the xaml, I don't know if the binding is setup correctly.

public User User
{
    get { return App.TheUser; }
    set
    { 
        if(App.TheUser!= null)
        App.TheUser = value;
    }

    //User class 
    public class User : Base //Base class implements INotifyPropertyChanged
    {
        private int _id
        public int Id {
            get{
                return this._id;
            }
            set{
                this._id = value;
                OnPropertyChanged("Id");
            }
        }

        private string _name;
        public string Name {
            get{
                return this._name;
            }
            set{
                this._name = value;
                OnPropertyChanged("Name");
            }
        }

        private ObservableCollection<Product> _products;
        public ObservableCollection<Product> Products
        {
            get{
                return this._products;                
            }
            set{
                this._products = value;
                OnPropertyChanged("Products");
            }
        } 
    }
}

so your listview is not bound to anything...

<ListView x:Name="UserListView"
          ItemsSource={Binding Products}
          SelectedItem="{Binding SelectedItemCommand}">