【问题标题】:Optimal way to replace ObservableCollection item when user click on databound CollectionView item当用户单击数据绑定的 CollectionView 项目时替换 ObservableCollection 项目的最佳方法
【发布时间】:2019-10-05 09:03:00
【问题描述】:

我是 Xamarin 表单 DataBinding 和 ObservableCollections 的新手。

我的问题是当我替换 ObservableCollection 中的项目时收到通知。让我告诉你我的目标。首先,有一点问题背景:

  • ObservableCollection 在 vi​​emModel 上,例如 ObservableCollection。
  • 该集合绑定到 Xamarin CollectionView,显示一些客户信息和一个用于更新客户状态的按钮。
  • 为了响应按钮点击事件,我使用 Rest 服务并发布帖子以更新点击的客户。
  • Post 方法返回一个新项目:修改后的客户

此时,我想知道更新集合的最佳方法是刷新我的用户界面。

我知道我可以更新 Item 的属性,但要让这种方式工作,我必须在我的客户(POCO 对象)上实现 INotifyPropertyChange。这不是问题,但有时 Rest 服务更新了很多属性,我宁愿将 ObservableCollection 中已编辑的客户替换为 Post 方法返回的新客户,而不是一一更新属性。

所以,我用这段代码替换了集合上的对象,并且工作正常:

var index = viewModel.Items.IndexOf(originalCustomer);
viewModel.Items[index] = updatedCustomer;

但是这种方式涉及使用 Collection.IndexOf(customer) 获取要替换的项目的索引,这似乎是一个 O(n) 操作。 ¿有什么方法可以直接在 O(1) 复杂度的点击事件上获取点击客户的索引?

提前致谢。

【问题讨论】:

    标签: c# xamarin data-binding collections time-complexity


    【解决方案1】:

    但是这种方式涉及使用 Collection.IndexOf(customer) 获取要替换的项目的索引,这似乎是一个 O(n) 操作。 ¿ 有什么方法可以在 O(1) 复杂度的点击事件上直接获取点击客户的索引?

    如果你想在Button点击事件中获取当前索引,我建议你可以绑定Collectionview SelectedItem,那么当你改变selecteditem时你可以得到这个索引。请确认您设置了 SelectedMode=Single。

    我为你制作简单,请看:

     <StackLayout>
            <CollectionView
                ItemsSource="{Binding customers}"
                SelectedItem="{Binding selecteditem}"
                SelectionMode="Single">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding Name}" />
                            <Label Text="{Binding Age}" />
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
    
            <Button
                x:Name="btn1"
                Clicked="Btn1_Clicked"
                Text="Get Index" />
        </StackLayout>
    
    public partial class Page2 : ContentPage, INotifyPropertyChanged
    {
        public ObservableCollection<customer> customers { get; set; }
        private customer _selecteditem;
        public customer selecteditem
        {
            get { return _selecteditem; }
            set
            {
                _selecteditem = value;
                RaisePropertyChanged("selecteditem");
            }
        }
        public Page2()
        {
            InitializeComponent();
            customers = new ObservableCollection<customer>()
            {
                new customer(){Name="cherry",Age=28},
                new customer(){Name="Wendy",Age=28},
                new customer(){Name="Jessie",Age=28},
                new customer(){Name="Barry",Age=28},
                new customer(){Name="Jason",Age=28},
                new customer(){Name="Annine",Age=28},
                new customer(){Name="Jack",Age=28},
                new customer(){Name="Leo",Age=28},
            };
            this.BindingContext = this;
    
        }
    
        private void Btn1_Clicked(object sender, EventArgs e)
        {
            var index = customers.IndexOf(selecteditem);
            Console.WriteLine("Current index is {0}",index);
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    
    
        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    【讨论】:

    • 但是在按钮点击事件中,我可以通过按钮绑定上下文获取点击的项目,所以,我不需要绑定到 SelectedItem 属性。无论如何,您使用 customer.IndexOf(item) 来获取项目索引,这是我的问题:¿有什么方法可以在不使用 indexOf 的情况下获取单击项目的索引(以 O(1) 方式)?
    • @Fran,如果你想直接获取item索引,不要使用indexof(item),我建议你可以尝试在Customer类中添加一个int类型的属性作为ID,作为CollectionView selectedindex,所以可以从Item中获取Id。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多