1

Это мой код:Удалить элемент в ListView Разливное

public partial class MyGS: ContentPage { 
    public MyGS() { 
    InitializeComponent(); 
    BindingContext = new MyGSViewModel(); 
    } 


public class MyGSViewModel: INotifyCollectionChanged { 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    public ObservableCollection <SchItem> Items {get;private set;} 

    public MyGSViewModel() { 
    Items = new ObservableCollection<SchItem>(); 
    //Item Population 

    public void removeItem(int rid, int lid) { 
    SchItem myItem = Items[lid]; 
    Items.Remove(myItem); 
    CollectionChanged ? .Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, myItem)); 
    } 
} 

public class SchItem { 
    public int realm_id {get;set;} 
    public int list_id {get;set;} 

    public ICommand TapCommand { 
    get {return new Command(() => { 
    Debug.WriteLine("COMMAND: " + list_id); 
    MyGSViewModel gsvm = new MyGSViewModel(); 
    gsvm.removeItem(realm_id, list_id); 
     }); 
    } 
    } 
} 
} 

Когда метод RemoveItem не называется вид не обновляется, и элемент будет не удален из ListView, может быть, проблема о CollectionChanged но Я не понимаю, как это исправить.

Примечание: Отладка в устройстве Android

ответ

1

Пару вещей. Обычно System.ComponentModel.INotifyPropertyChanged используется вместо INotifyCollectionChanged. Если вы переключитесь на что, а также реализовать более общий обязательный шаблон, ваш ViewModel будет выглядеть следующим образом:

public class MyGSViewModel: INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 

    public ObservableCollection <SchItem> Items { 
     get { return _items; } 
     private set { 
      if(_items != value) { 
       _items = value; 
       OnPropertyChanged(); //Execute the event anytime an object is removed or added 
      } 
     } 
    } 

    public MyGSViewModel() { 
     Items = new ObservableCollection<SchItem>(); 
     //Item Population 
    } 

    public void removeItem(int rid, int lid) { 
     SchItem myItem = Items[lid]; 
     Items.Remove(myItem); //If an object is removed, the OnPropertyChanged() method will be run from 'Items's setter 
    } 

    protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) { 
     PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 
    } 
} 

Я также предлагаю двигаться методом OnPropertyChanged и PropertyChanged события в базовую ViewModel, так что все ваши ViewModels может наследовать от базы, и вы не дублируете этот код повсюду.

* Редактировать: Только что заметил, что у вас есть TapCommand, определенный в вашем классе SchItem. Там вы создаете новый экземпляр MyGSViewModel каждый раз, когда выполняется эта команда. Поэтому, если все в вашем MyGSViewModel не статично (что я не рекомендую), это никогда не будет влиять на вашу страницу MyGS. В дополнение к тому, что я предложил выше, я бы предложил использовать событие Tapped вместо Command, поскольку вам необходимо передать несколько параметров в ваш метод removeItem.

Чтобы сделать это ...

В вашем XAML:

<Button Tapped="OnItemTapped"/> 

-ИЛИ-

<Label> 
    <Label.GestureRecognizers> 
    <TapGestureRecognizer Tapped="OnItemTapped"/> 
    </Label.GestureRecognizers> 
</Label> 

В вашем MyGSContentPage:

public partial class MyGS : ContentPage { 

    private MyGSViewModel _viewModel; 

    public MyGS() { 
     InitializeComponent(); 
     BindingContext = _viewModel = new MyGSViewModel(); 
    } 

    private void OnItemTapped(object sender, EventArgs e) { 
     SchItem item = (SchItem)((Image)sender).BindingContext; 

     if(item == null) { return; } 

     _viewModel.removeItem(item.realm_id, item.list_id); 
    } 
} 
+0

О редактировании, я получил 'System.In validCastException: указанный сброс недействителен. 'возможно, потому что у меня есть команда tap в классе определения элемента? Редактировать: Я получил обратно SchItem, а не MyGSViewModel как CommandParameter – Segamoto

+0

@Segamoto O правильно, потому что 'BindingContext' является объектом, поскольку он находится в' ListView' ... поэтому в этом случае я определенно рекомендую использовать 'Tapped' мероприятие. Я отредактирую свой ответ. – hvaughan3

+0

@Segamoto Проверить сейчас – hvaughan3

Смежные вопросы