Оптимальный способ заменить элемент ObservableCollection, когда пользователь нажимает на элемент CollectionView, связанный с данными - PullRequest
0 голосов
/ 05 октября 2019

Я новичок с формами Xamarin DataBinding и ObservableCollections.

У меня вопрос об уведомлении, когда я заменяю элемент в ObservableCollection. Позвольте мне рассказать вам о моей цели. Во-первых, немного проблемного контекста:

  • ObservableCollection находится на viemModel, например ObservableCollection <"Customer">.
  • Коллекция привязана к Xamarin CollectionView, показывая некоторую информацию о клиенте и кнопку для обновления статуса клиента.
  • В ответ на событие нажатия кнопки я использую службы отдыха и создаю сообщение для обновления. клиент, по которому щелкнули.
  • Метод Post возвращает новый элемент: измененный клиент

На данный момент я задаюсь вопросом, как лучше всего обновить коллекцию, чтобы мой пользовательский интерфейс обновился.

Я знаю, что могу обновить свойства Item, но чтобы это работало, я должен внедрить INotifyPropertyChange для моего клиента (объект POCO). Это не проблема, но иногда существует много свойств, обновленных службой Rest, и я бы предпочел заменить отредактированного клиента в ObservableCollection новым, возвращенным методом Post, а не обновлять свойства одно за другим.

Итак, я заменяю объект коллекции на этот код и работает нормально:

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

Но этот способ включает получение индекса заменяемого элемента с помощью Collection.IndexOf (customer), и это, похоже,быть O (n) операция. ¿Есть ли способ получить индекс кликаемого клиента непосредственно по событию клика со сложностью O (1)?

Заранее спасибо.

1 Ответ

0 голосов
/ 07 октября 2019

Но этот способ подразумевает получение индекса элемента, подлежащего замене, с помощью Collection.IndexOf (customer), и это, по-видимому, операция O (n). Any Есть ли способ получить индекс кликаемого клиента непосредственно по событию щелчка со сложностью O (1)?

Если вы хотите получить текущий индекс в событии нажатия кнопки, я предлагаю вам связать CollectionviewSelectedItem, тогда вы можете получить этот индекс при изменении 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));
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...