当用户单击数据绑定的集合视图项时替换"可观察集合"项的最佳方法



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

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

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

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

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

因此,我用以下代码替换了集合上的对象,并且工作正常:

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

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

提前谢谢。

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

如果要在按钮单击事件中获取当前索引,我建议您绑定Collectionview SelectedItem,然后在更改Selecteditem时获取此索引。请确认您设置了选择模式=单身。

我为您创建简单,请看一下:

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

最新更新