【问题标题】:Xamarin form update listView itemSourceXamarin 表单更新列表查看 itemSsource
【发布时间】:2015-03-07 14:54:40
【问题描述】:

好的,我有一个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

【问题讨论】:

  • 您可以从 INotifyPropertyChanged 继承您的视图模型(如果您正在使用)
  • 看看这个link 可能对你有帮助..

标签: c# .net xamarin xamarin.forms


【解决方案1】:

您可以将 ListView 的 ItemsSource 设置为 null,然后再次将其设置回来,这会重新加载表。 http://forums.xamarin.com/discussion/18868/tableview-reloaddata-equivalent-for-listview

【讨论】:

    【解决方案2】:

    好的,这就是我解决问题的方法,首先我创建了一个“包装器”,它为我作为 ItemSource 的列表实现 INotifyPropertyChanged,如下所示:

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

    【讨论】:

    • 终于明白了,谢谢!
    【解决方案3】:

    您可以定义基本视图模型并从 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&lt;YOURLISTCLASS&gt;列表

    您在 ViewModel(例如 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); }
    } 
    

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      将 List 更改为 ObservableCollection 并实施 INotifyPropertyChanged 以使更改反映在您的 ListView 中。

      【讨论】:

      • 谁应该实施 INotifyPropertyChanged ?
      • 你应该这样做。用它扩展你的项目模型:msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx
      • 你这是什么意思?
      • 它被提到你应该这样做,看起来你误读了我的问题。
      • 我修改了所有列表而不是单个对象,有没有办法做到这一点,而不是让 Filiale 的每个字段触发属性更改?
      【解决方案5】:

      只需将您的System.Collections.Generic.List 转换为System.Collections.ObjectModel.ObservableCollection,然后再将其绑定到ListView

      【讨论】:

        【解决方案6】:

        这是我目前从我正在开发的应用程序中提取的这种模式的实现,尽可能简洁。

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

        【讨论】:

          猜你喜欢
          • 2019-10-15
          • 1970-01-01
          • 1970-01-01
          • 2020-06-30
          • 1970-01-01
          • 2021-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多