2016-11-25 13 views
1

MVVMを遵守しながらObservableCollectionから項目を削除したいとします。私はこの作業を理解していますが、ロジックをかなりよく理解して実装していると思いますが、アイテムはビュー内で決して削除されません。MVVMを使用してObservableCollectionからselectedItemを削除します。

私はブレークポイントでアプリケーションをトレースしており、selectedProjectの値が正しく読み取られています。また、remove文の前後でCollectionのサイズをチェックする変数を追加しました。これは同じ値であったため、項目を削除しません。私の質問はなぜですか?私は何を逃したのですか?私が遵守していないルールは何ですか? .NETを使い慣れていない

**私はCodeFirst DBからプロジェクトのObservableCollectionを返すためにWCFサービスを使用しています。これは、ユーザーがプロジェクトビューを開くとすぐに呼び出されます。

ビュー

<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"/> 

のViewModel

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" /> 

ViewModelに、モデルとの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(表示)の選択を変更します。 Two-Way-Bindingでは、ViewModelsプロパティSelectedItemが更新されます。 私は自分の答えを編集し、有効な解決策を投稿します。 –

+0

トーマス、ありがとう。私が理解できないことは、ブレークポイントをトレースすると、正しいselectedItemがViewModelに渡されたことがわかりますが、removeの呼び出しによってビューのリストが変更されることはありません。 –

0

私は、OnPropertyChangedを(「ProjectList」)がビューを更新するための通知を調達する項目を削除した後に呼び出される必要があると思います。

+0

ない修正。 –

関連する問題