Update/Save data of entry cell of Listview into DB using MVVM?

Hello, I am new with Xamarin forms, Here I have created a ListView having Labels & Entry cell (Created CustomCell) List Populate details of a product and it suggest to enter amount (entry cell) to Place Order by clicking on Save button. I manage to create a ViewCell and populating data. But don't know how to use the values which will be entered into entrycell by users. Also need to update/Save records on button click. Please guide how to do it?
Following is what I tried--
RetailerListPage is created below. In this case it's my View

public class RetailerListPage : ContentPage
{
    public RetailerListPage()
    {
        BackgroundColor = Color.White;
        Title = "Retailer List";

        BindingContext = new RetailerListPageViewModel();

        ListView listview = new ListView();
        listview.RowHeight = 100;

        listview.ItemTemplate = new DataTemplate(typeof(CustomCell));

        listview.SetBinding(ListView.ItemsSourceProperty, "RetailerList");

        Content = listview;
    }

    public class CustomCell : ViewCell
    {
        public CustomCell()
        {
           #region Code that Customizes Cell

            AbsoluteLayout cellView = new AbsoluteLayout();
            var retailernameLabel = new Label();
            AbsoluteLayout.SetLayoutBounds(retailernameLabel, new Rectangle(5, 12, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
            retailernameLabel.SetBinding(Label.TextProperty, new Binding("Retailer_nm"));
            retailernameLabel.FontSize = 18;
            retailernameLabel.TextColor = Color.FromHex("#434343");
            cellView.Children.Add(retailernameLabel);

            var txtAmt = new Entry();
            AbsoluteLayout.SetLayoutBounds(txtAmt, new Rectangle(5, 32, 500, 60));
            txtAmt.SetBinding(Entry.TextProperty, new Binding("InputAmt"));
            txtAmt.Keyboard = Keyboard.Numeric;
            txtAmt.TextColor = Color.Black;
            cellView.Children.Add(txtAmt);

            this.View = cellView;

            View = new StackLayout()
            {
              Children = { cellView }
            };
            #endregion
        }
    }
 }

DSO_beat_Retailer_mapping containing all the properties which is my Modal

public class DSO_beat_Retailer_mapping: INotifyPropertyChanged
{
    public string _inputAmt;  //NEWLY ADDED
    public int _id;
    public string _DSO_CD;
    public string _Beat_id;
    public string _Retailer_cd;
    public string _Retailer_nm;
    public string _email;
    public string _mobile;
    public DateTime _birth_dt;
    public DateTime _Anniversary_dt;
    public DateTime _Lst_sync_dt;
    public string InputAmt
    {        get        {            return _inputAmt;        }
            set          {            _inputAmt = value;
                           OnPropertyChanged("inputAmt");    }
    }

    public int Id
    {        get        {            return _id;        }
             set        {            _id = value;
                           OnPropertyChanged("ID");        }
    }

    public string DSO_CD
    {        get        {            return _DSO_CD;        }
             set        {            _DSO_CD = value;
                         OnPropertyChanged("DSO_CD");   }
    }

    public string Beat_id
    {        get        {            return _Beat_id;        }
             set         {            _Beat_id = value;
                          OnPropertyChanged("Beat_id");        }
    }

    public string Retailer_cd
    {        get        {            return _Retailer_cd;        }
             set        {            _Retailer_cd = value;
                        OnPropertyChanged("Retailer_cd");        }
    }

    public string Retailer_nm
    {        get        {            return _Retailer_nm;        }
             set        {            _Retailer_nm = value;
                        OnPropertyChanged("Retailer_nm");        }
    }

    public string email
    {        get        {            return _email;        }
             set        {            _email = value;
                        OnPropertyChanged("email");        }
    }

    public string mobile
    {        get        {            return _mobile;        }
            set          {            _mobile = value;
                        OnPropertyChanged("mobile");        }
    }

    public DateTime birth_dt
    {        get        {            return _birth_dt;        }
             set        {            _birth_dt = value;
                        OnPropertyChanged("birth_dt");        }
    }

    public DateTime Anniversary_dt
    {        get        {            return _Anniversary_dt;        }
            set          {            _Anniversary_dt = value;
                        OnPropertyChanged("Anniversary_dt");        }
    }

    public DateTime Lst_sync_dt
    {        get        {            return _Lst_sync_dt;        }
             set        {             _Lst_sync_dt = value;
                        OnPropertyChanged("Lst_sync_dt");        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
            this.PropertyChanged(this, e);
        }
    }
}

RetailerListPageViewModel is my View Model which Implements the INotifyPropertyChanged

public class RetailerListPageViewModel : INotifyPropertyChanged
{
    private List<DSO_beat_Retailer_mapping> retailerList;

    public RetailerListPageViewModel()
    {
        #region Here data inserted for test purpose 
        //DSO_beat_Retailer_mapping retailerlst = new DSO_beat_Retailer_mapping
        //{
        //    InputAmt = "200",
        //    _id = 1,
        //    DSO_CD = "123",
        //    Beat_id = "111",
        //    Retailer_nm = "XYZ RETAILER",
        //    email = "ZYZ@ABCD.com",
        //    mobile = "1234567890",
        //    birth_dt = DateTime.Now,
        //    Anniversary_dt = DateTime.Now,
        //    Lst_sync_dt = DateTime.Now
        //};

        //DSO_beat_Retailer_mapping retailerlst1 = new DSO_beat_Retailer_mapping
        //{
        //    InputAmt = "200",
        //    _id = 1,
        //    DSO_CD = "123",
        //    Beat_id = "111",
        //    Retailer_cd = "R123",
        //    Retailer_nm = "XYZ RETAILER",
        //    email = "ZYZ@ABCD.com",
        //    mobile = "1234567890",
        //    birth_dt = DateTime.Now,
        //    Anniversary_dt = DateTime.Now,
        //    Lst_sync_dt = DateTime.Now
        //};
        #endregion

        CreateNewDB database = new CreateNewDB();
        //database.saveDSOReatilMap(retailerList);  
        //database.saveDSOReatilMap(retailerlst1);

       RetailerList = database.GetDSOReatilMap("Select * from DSO_beat_Retailer_mapping ").ToList();
    }

        public List<DSO_beat_Retailer_mapping> RetailerList
    {
        get { return retailerList; }

        set
        {
            retailerList = value;
            OnPropertyChanged("RetailerList");
        }
    }

    public Command btnSave
    {
        get
        {
            return new Command(() => {
                // Code to save List 

            });
        }
    }

Following class CreateNewDB contain the methods to access the database (In this case I have used SQLite )

public class CreateNewDB
{
    static object locker = new object ();
    SQLiteConnection database;

    public CreateNewDB ()
    {

        database = DependencyService.Get<ISQLite> ().GetConnection ();

        database.DropTable<DSO_beat_Retailer_mapping> ();
        database.CreateTable<DSO_beat_Retailer_mapping> ();
    }


    //DSO_beat_Retailer_mapping
    public IEnumerable<DSO_beat_Retailer_mapping> GetDSOReatilMap(string query)
    {
        lock (locker) {
            return database.Query<DSO_beat_Retailer_mapping> (query);
        }
    }

    public string saveDSOReatilMap(DSO_beat_Retailer_mapping item)
    {
        lock (locker) {
            database.Insert(item);
            return item.Retailer_cd;
        }
    }
//UPDATE DB  
public string UpdateDSOReatilMap(DSO_beat_Retailer_mapping item)
    {
        lock (locker)
        {
            database.Update(item);
            return item.Retailer_cd;
        }
    }
    public int DeleteDSOReatilMap(string empcd)
    {
        lock (locker) {
            return database.Delete<DSO_beat_Retailer_mapping> (empcd);
        }
    }


}

Answers

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    Can you tell me where is your save button. you can use entry completed trigger and save your data. that is like pressing the done button of your textpad.

  • GaneshParikhGaneshParikh USMember ✭✭

    Save Button will be on RetailerListPage i.e. on my View. Here I fail to add that. But If it is there then how to achieve it pls explain

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    You can directly trigger an event if you use.

    entry.completed trigger in your custom view cell.

    if you are using save command you have to check whether your entry value has been updated. what you can do is you can do a two way binding between your entry text and model text. when you press your save button check whether the model value has been changed and update the particular value in your database.

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    entry.SetBinding(Entry.TextProperty,new Binding("Your model entry text"),BindingMode.TwoWay)

  • GaneshParikhGaneshParikh USMember ✭✭

    Thank you.. @Maharshi.5212 Can you put some example relating to my code.??

  • GaneshParikhGaneshParikh USMember ✭✭

    @Maharshi.5212 I have Updated the custom cell by this txtAmt.SetBinding(Entry.TextProperty, new Binding("InputAmt",BindingMode.TwoWay)); also added the button btnSave But Don't know how to check Entry Value updated or not & also don't know how to update the list in Database. Please guide how to do it?

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    Just check your InputAmt . When you click on the save button. Your model value will be updated . You have to go through your entire list.

  • GaneshParikhGaneshParikh USMember ✭✭

    @Maharshi.5212 I am unable to Iterate over the list to update the records. How it can be done in this case??

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    Check this link https://developer.xamarin.com/api/type/Xamarin.Forms.BindingMode

    You need to use OneWaytoSoource and your entry text will be empty , if it is non empty update in the database.

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    txtAmt.SetBinding(Entry.TextProperty, new Binding("InputAmt",BindingMode.OneWayToSource));

    Your viewmodel will be updated .

    You have OnPropertyChanged event handler also, that itself can be used to check whether your entry is updated. Keep a flag

    public string InputAmt
    {
    get {return inputamt;}
    set
    {
    if(inputamt!=value)
    inputamt=value;
    OnPropertyChanged("InputAmt");
    }
    }

    protected void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged == null)
    return;
    EntryUpdatedFlag=true;
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    EntryUpdatedFlag is a public variable in the model.

    When you click your save item.

    Check where EntryUpdatedFlag is set to true in your model list. and then update the DB.

    If you use an index number of your model list that is also good, then you dont have to go through the entire list.

    That is the maximum i can give you help. Rest you have to figure out.

Sign In or Register to comment.