2016-11-25 64 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

遗憾的是没有修复。 –

相关问题