1

刪除項這是我的代碼:列表視圖中的自來水

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。如果切換到這一點,並實現了更常見的結合方式,你的視圖模型應該是這樣的:

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事件爲基本視圖模型,以便所有的ViewModels的可以從基地繼承,並且您沒有在任何地方都有重複的代碼。

*編輯:剛纔注意到你的TapCommand定義在你的SchItem類中。在那裏你每次運行這個命令都會新增一個新的實例。因此,除非您的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:指定的轉換無效。 '也許是因爲我在Item定義類中有tap命令? 編輯:我得到了SchItem而不是MyGSViewModel作爲CommandParameter – Segamoto

+0

@Segamoto O權利,因爲'BindingContext'是對象,因爲它在'ListView' ...所以在這種情況下,我一定會推薦使用'Tapped'事件。我會編輯我的答案。 – hvaughan3

+0

@Segamoto現在檢查 – hvaughan3