Список обновлений формы XamarinView itemSource

Хорошо, у меня есть объект ListView, который имеет List<Filiale> как ItemSource, и я хотел бы обновлять ItemSource при каждом изменении списка объектов. ListView имеет персонализированный ItemTemplate На данный момент я сделал это:

public NearMe ()
{
    list=jM.ReadData ();
    listView.ItemsSource = list;
    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){
        //DOSOMETHING
        list=newList;
}

Как вы можете видеть в методе TextChanged, я назначаю новый список предыдущему, но в представлении нет никаких изменений. В ViewCell, который я создал, я назначаю текстовое поле меток с SetBinding


person Davide Quaglio    schedule 09.01.2015    source источник
comment
вы можете наследовать свою модель представления (если используете) от INotifyPropertyChanged   -  person SoftSan    schedule 09.01.2015
comment
Ознакомьтесь с этой ссылкой. что может тебе помочь..   -  person Femil Shajin    schedule 12.01.2015


Ответы (6)


Вы можете установить для ItemsSource ListView значение null, а затем снова установить его, что приведет к перезагрузке таблицы. http://forums.xamarin.com/discussion/18868/tableview-reloaddata-equivalent-for-listview

person danfordham    schedule 31.03.2015

Хорошо, вот как я решил проблему, прежде всего я создал «оболочку», которая реализует INotifyPropertyChanged для списка, который я использовал в качестве ItemSource, например:

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();
        }

Затем в классе NearMe:

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 ();
            }
person Davide Quaglio    schedule 12.01.2015
comment
Наконец-то я понял это, спасибо! - person Mario Galván; 29.04.2016

Вы можете определить базовую модель представления и наследовать ее от 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;
    }

то в вашей модели представления (например, JM) будет унаследовано от BaseViewModel и может быть создано ObservableCollection<YOURLISTCLASS> List

Также ваши поля в ViewModel (Ex. JM) должны быть реализованы следующим образом:

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

Надеюсь это поможет.

person SoftSan    schedule 09.01.2015

Измените список на ObservableCollection и внедрите INotifyPropertyChanged, чтобы изменения отражались в вашем ListView.

person Martijn00    schedule 09.01.2015
comment
Кто должен реализовать INotifyPropertyChanged? - person Davide Quaglio; 09.01.2015
comment
Вы должны сделать это. Расширьте с его помощью свою модель элемента: msdn.microsoft. com/en-us/library/ms743695(v=vs.110).aspx - person Martijn00; 09.01.2015
comment
Что ты имеешь в виду? - person Martijn00; 09.01.2015
comment
Это было сослано на «Вы должны это сделать», похоже, вы неправильно поняли мой вопрос. - person Davide Quaglio; 09.01.2015
comment
Я изменяю весь список, а не один объект, есть ли способ сделать это вместо того, чтобы изменять свойства каждого поля Fire Fire? - person Davide Quaglio; 09.01.2015

Просто преобразуйте System.Collections.Generic.List в System.Collections.ObjectModel.ObservableCollection перед привязкой к ListView.

person Ivan B. Prado    schedule 10.02.2020

Вот моя текущая реализация этого шаблона, извлеченная из приложения, над которым я работаю, настолько кратко, насколько это возможно.


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);
        }
    }

}



person JR Lawhorne    schedule 08.02.2020