2016-11-25 66 views
1

我想在遵守MVVM的同時從ObservableCollection中移除一個項目。我理解這個任務,我認爲我很瞭解這個邏輯並且已經實現了它,但是這個項目在視圖中永遠不會被刪除。使用MVVM從ObservableCollection中移除selectedItem

我已經用斷點跟蹤了應用程序,正在正確讀取selectedProject的值。我還添加了變量來檢查remove語句之前和之後的Collection大小,它們是相同的值,因此它不會刪除該項目。我的問題是爲什麼?我錯過了什麼?我沒有遵守什麼規則?對.NET來說很新。

**我正在使用WCF服務,從我的CodeFirst數據庫返回一個ObservableCollection項目,並且只要用戶打開Projects視圖,就會調用它。

查看

<ListBox ItemsSource="{Binding ProjectList, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedProject}" SelectedIndex="{Binding ProjectIndex}" BorderThickness="0" Margin="60,195,218.8,212.4"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding ProjectName}"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Command="{Binding DeleteCommand}" Content="Up" HorizontalAlignment="Left" Margin="563,195,0,0" VerticalAlignment="Top" Height="35" Width="75"/> 

視圖模型

private ObservableCollection<Project> _projectList; 
public ObservableCollection<Project> ProjectList 
    { 
     get 
     { 
      var q = client.ReturnProjects().ToList(); 
      _projectList = new ObservableCollection<Project>(q.ToList()); 
      return _projectList; 
     } 
     set 
     { 
      _projectList = value; 
      OnPropertyChanged("ProjectList"); 
     } 

public int SelectedProject 
    { 
     get { return _selectedProject; } 
     set 
     { 
      _selectedProject = value; 
      OnPropertyChanged("SelectedProject"); 
     } 
    } 

由命令執行的方法如下,該命令被擊中並調用的方法。

public void DeleteProject() 
     { 

      if (SelectedProject != null) 
      { 
       ProjectList.Remove(SelectedProject); 
      } 
     } 

回答

0

您需要對SelectedItem屬性進行雙向綁定。

查看

<ListBox ItemsSource="{Binding ProjectList}" 
      SelectedItem="{Binding SelectedProject, Mode=TwoWay}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Name}" /> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Command="{Binding DeleteCommand}" 
      Content="Delete" 
      HorizontalAlignment="Right" 
      VerticalAlignment="Bottom" /> 

視圖模型,模型的ICommand實現

public class ViewModel : INotifyPropertyChanged 
{ 
    public ViewModel() 
    { 
     var q = new[] { new Project() { Name = "A" }, new Project() { Name = "B" }, new Project() { Name = "C" } }; 
     ProjectList = new ObservableCollection<Project>(q); 
    } 

    private ObservableCollection<Project> _projectList; 

    public ObservableCollection<Project> ProjectList 
    { 
     get 
     { 
      return _projectList; 
     } 
     set 
     { 
      _projectList = value; 
      OnPropertyChanged("ProjectList"); 
     } 
    } 

    Project _selectedProject; 
    public Project SelectedProject 
    { 
     get { return _selectedProject; } 
     set 
     { 
      _selectedProject = value; 
      OnPropertyChanged("SelectedProject"); 
     } 
    } 

    public ICommand DeleteCommand => new SimpleCommand(DeleteProject); 

    private void DeleteProject() 
    { 

     if (SelectedProject != null) 
     { 
      ProjectList.Remove(SelectedProject); 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class Project 
{ 
    public string Name { get; set; } 
} 

public class SimpleCommand : ICommand 
{ 
    Action _execute; 
    public SimpleCommand(Action execute) 
    { 
     this._execute = execute; 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecute(object parameter) => true; 

    public void Execute(object parameter) 
    { 
     _execute(); 
    } 
} 
+0

我加了'Mode = TwoWay',這並沒有解決問題。我也不明白爲什麼它應該有SelectedItem只允許我檢索我想要刪除的項目。 –

+0

用戶更改UI中的選擇(視圖)。使用雙向綁定時,ViewModels屬性SelectedItem被更新。 我將編輯我的答案併發布工作解決方案。 –

+0

這很有道理,謝謝。我不明白的是,當我使用斷點跟蹤時,我可以看到正確的selectedItem已經傳遞給ViewModel,但是調用remove方法並不會改變視圖上的列表。 –

0

我認爲OnPropertyChanged(「ProjectList」)需要在刪除項目以調出更新視圖的通知後調用。

+0

遺憾的是沒有修復。 –

相關問題