使用 MVVM 从 ObservableCollection 中删除 selectedItem
Removing selectedItem from ObservableCollection using MVVM
我想在遵守 MVVM 的同时从 ObservableCollection 中删除一个项目。我理解这个任务,我想我已经很好地理解了逻辑并且已经实现了它,但是该项目从未在视图中被删除。
我已使用断点跟踪应用程序并且正确读取了 selectedProject 的值。我还添加了变量来检查删除语句前后的集合大小,它们是相同的值,因此它不会删除该项目。我的问题是为什么?我错过了什么?我没有遵守什么规则? .NET 的新手。
**我正在使用 WCF 服务,return 来自我的 CodeFirst 数据库的项目的 ObservableCollection,一旦用户打开项目视图,就会调用它。
查看
<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);
}
}
我认为删除项目后需要调用 OnPropertyChanged("ProjectList") 以引发更新视图的通知。
ObservableCollection 必须与模型层进行交互。
也许你需要这个:
https://blogs.msdn.microsoft.com/bethmassi/2009/05/08/using-the-wpf-observablecollection-with-ef-entities/
您需要 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();
}
}
我想在遵守 MVVM 的同时从 ObservableCollection 中删除一个项目。我理解这个任务,我想我已经很好地理解了逻辑并且已经实现了它,但是该项目从未在视图中被删除。
我已使用断点跟踪应用程序并且正确读取了 selectedProject 的值。我还添加了变量来检查删除语句前后的集合大小,它们是相同的值,因此它不会删除该项目。我的问题是为什么?我错过了什么?我没有遵守什么规则? .NET 的新手。
**我正在使用 WCF 服务,return 来自我的 CodeFirst 数据库的项目的 ObservableCollection,一旦用户打开项目视图,就会调用它。
查看
<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);
}
}
我认为删除项目后需要调用 OnPropertyChanged("ProjectList") 以引发更新视图的通知。
ObservableCollection 必须与模型层进行交互。 也许你需要这个: https://blogs.msdn.microsoft.com/bethmassi/2009/05/08/using-the-wpf-observablecollection-with-ef-entities/
您需要 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();
}
}