【问题标题】:Xamarin Custom Control binding collectionChanged to IEnumerable ItemsSourceXamarin 自定义控件绑定集合更改为 IEnumerable ItemsSource
【发布时间】:2018-02-27 03:16:48
【问题描述】:

我有一个自定义控件,它接受一个对象列表并以列表视图的形式呈现它们。

public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable<object>), typeof(MyCustomControl), null);
    public IEnumerable<object> ItemsSource
    {
        get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
        set{ SetValue(ItemsSourceProperty, value);}
    }

来自 ViewModel 我会将ItemsSource 绑定到ObservableCollection&lt;object&gt;,并且我希望我的自定义控件能够侦听 ObservableCollection 上的 collectionchanged 事件,而不是 propertychanged。

ListView 一些如何能够监听集合更改并刷新其视图,我试图从 Xamarin github 中找到代码,但没有找到监听器绑定的位置。

任何解决方案,我如何从我的自定义控件中收听集合?

【问题讨论】:

    标签: xamarin collections observablecollection inotifycollectionchanged


    【解决方案1】:

    您可以使用ObservableCollection&lt;T&gt;.CollectionChanged 将事件添加到您的收藏中。更多信息here。 您可以使用如下回调机制处理视图中的更改

    在你的 ViewModel 中是这样的

    public ObservableCollection<Item> myObservableList { get; set; }
    MyChangeHandler handler;
    
    //Pass a callback to your viewModel to listen to changes in your view
    public YourViewModel(MyChangeHandler handler)
    {
       this.myObservableList = new ObservableCollection<Item>();
       this.myObservableList.CollectionChanged += this.OnCollectionChanged;
    }
    
    //Handle collection changes
    void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
    //...Call your custom control method here
        handler.someMethod("List changed");
    }
    
    public interface MyChangeHandler{
        void someMethod(string value);
    }
    

    在您的自定义视图中

    class MyView: ContentView,MyChangeHandler{
        public MyView(){
            var vm = new YourViewModel(this);
        } 
    
        public someMethod(string value){
            ///Handle changes in your view
        }
    }
    

    【讨论】:

    • 如何在 CustomControl 中实现 collctionchanged 事件而不是从视图模型中调用?
    • 这取决于您的应用程序设计。您可以在单个类或(视图)中编写所有代码,也可以在一些可管理的模块中单独编写代码,从长远来看,遵循某种模式可以节省您的时间。
    【解决方案2】:

    好的,回答我自己的帖子

    许多其他人建议我使用 MessagingCenter、ViewModel 中的 Collection 事件、在自定义控件中创建自定义事件处理程序...这些都是解决方法,而不是解决方案。

    如果它的错误那么解决将是最好的解决方案,但由于 bindableproperty 的实现方式,我们能够使用实际提供的设计来实现这一点。

    所以在自定义控件中

    protected override void OnPropertyChanged(string propertyName)
    {
        if(propertyName == CustomView.ItemsSourceProperty.PropertyName)
        {
            if (ItemsSource != null && ItemsSource is INotifyCollectionChanged collection)
            {
                    collection.CollectionChanged -= ItemsSourceCollectionChanged;
                    collection.CollectionChanged += ItemsSourceCollectionChanged;
            }
    
        }
    
        base.OnPropertyChanged(propertyName);
    }
    
    private void ItemsSourceCollectionChanged(object s, EventArgs e)
    {
        //Handle collection changed event
    }
    

    当 ItemsSource 属性发生变化时,它会重新订阅 collectionchanged 事件。

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2015-09-08
      • 1970-01-01
      相关资源
      最近更新 更多