Xamarin form update listView itemSource

后端 未结 6 841
闹比i
闹比i 2021-01-04 18:28

Ok I have a ListView object which have a List as ItemSource and I\'d like to refresh the ItemSource whene

相关标签:
6条回答
  • 2021-01-04 18:35

    Just convert your System.Collections.Generic.List to a System.Collections.ObjectModel.ObservableCollection before binding it to the ListView.

    0 讨论(0)
  • 2021-01-04 18:38

    Ok here is how I solved the problem, first of all I created a "wrapper" that implement INotifyPropertyChanged for the list that I was taking as ItemSource like this :

    public class Wrapper : INotifyPropertyChanged
        {
            List<Filiale> list;
            JsonManager jM = new JsonManager ();//retrieve the list
    
            public event PropertyChangedEventHandler PropertyChanged;
            public NearMeViewModel ()
            {
                list = (jM.ReadData ()).OrderBy (x => x.distanza).ToList();//initialize the list
            }
    
            public List<Filiale> List{ //Property that will be used to get and set the item
                get{ return list; }
    
                set{ 
                    list = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, 
                            new PropertyChangedEventArgs("List"));// Throw!!
                    }
                }
            }
    
            public void Reinitialize(){ // mymethod
                List = (jM.ReadData ()).OrderBy (x => x.distanza).ToList();
            }
    

    Then in the NearMe class:

    Wrapper nearMeVM = new Wrapper();
    public NearMe ()
            {
    
                Binding myBinding = new Binding("List");
                myBinding.Source = nearMeVM;
                myBinding.Path ="List";
                myBinding.Mode = BindingMode.TwoWay;
                listView.SetBinding (ListView.ItemsSourceProperty, myBinding); 
                listView.ItemTemplate = new DataTemplate(typeof(FilialeCell));
                searchBar = new SearchBar {
                    Placeholder="Search"
                };
                searchBar.TextChanged += (sender, e) => {
                    TextChanged(searchBar.Text);
                };
                var stack = new StackLayout { Spacing = 0 };
                stack.Children.Add (searchBar);
                stack.Children.Add (listView);
                Content = stack;
            }
    public void TextChanged(String text){
                if (!String.IsNullOrEmpty (text)) {
                    text = text [0].ToString ().ToUpper () + text.Substring (1);
                    var filterSedi = nearMeVM.List.Where (filiale => filiale.nome.Contains (text));
                    var newList = filterSedi.ToList ();
                    nearMeVM.List = newList.OrderBy (x => x.distanza).ToList ();
                } else {
                    nearMeVM.Reinitialize ();
                }
    
    0 讨论(0)
  • 2021-01-04 18:40

    Change List to ObservableCollection and implement INotifyPropertyChanged to have changes reflect in your ListView.

    0 讨论(0)
  • 2021-01-04 18:42

    You can define a base view model and inherit it from INotifyPropertyChanged

    public abstract class BaseViewModel : INotifyPropertyChanged
        {
            protected bool ChangeAndNotify<T>(ref T property, T value, [CallerMemberName] string propertyName = "")
            {
                if (!EqualityComparer<T>.Default.Equals(property, value))
                {
                    property = value;
                    NotifyPropertyChanged(propertyName);
                    return true;
                }
    
    
                return false;
            }
    
    
            protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
        }
    

    then in your viewmodel (Ex. JM) will be inherit from BaseViewModel and can create ObservableCollection<YOURLISTCLASS> List

    Also your fields in ViewModel (Ex. JM) should implement like following:

    public const string FirstNamePropertyName = "FirstName";
    private string firstName = string.Empty;
    public string FirstName 
    {
        get { return firstName; }
        set { this.ChangeAndNotify(ref this.firstName, value, FirstNamePropertyName); }
    } 
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-04 18:54

    You can set the ItemsSource of the ListView to null, and then set it back again, that does a table reload. http://forums.xamarin.com/discussion/18868/tableview-reloaddata-equivalent-for-listview

    0 讨论(0)
  • 2021-01-04 18:55

    Here is my current implementation of this pattern extracted from an app I'm working on, as concisely as I could make it.

    
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    namespace MyNamespace
    {
        // This base view model takes care of implementing INotifyPropertyChanged
        // In your extended View Model classes, use SetValue in your setters.
        // This will take care of notifying your ObservableCollection and hence
        // updating your UI bound to that collection when your view models change.
        public abstract class BaseViewModel : INotifyPropertyChanged
        {
            protected void SetValue(ref T backingField, T value, [CallerMemberName] string propertyName = null)
            {
                if (EqualityComparer.Default.Equals(backingField, value)) return;
                backingField = value;
                OnPropertyChanged(propertyName);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        // Using MvvM, this would likely be a View Model class.
        // However, it could also be a simple POCO model class
        public class MyListItem : BaseViewModel
        {
            private string _itemLabel = "List Item Label";
            public string Label
            {
                get => _itemLabel;
                set => SetValue(ref _itemLabel, value);
            }
        }
    
        // This is your MvvM View Model
        // This would typically be your BindingContext on your Page that includes your List View
        public class MyViewModel : BaseViewModel
        {
            private ObservableCollection _myListItemCollection
                = new ObservableCollection();
    
            public ObservableCollection MyListItemCollection
            {
                get { return _myListItemCollection; }
                set => SetValue(ref _myListItemCollection, value);
            }
        }
    
    }
    
    
    
    
    0 讨论(0)
提交回复
热议问题