c# - 使用 MVVM 从 ObservableCollection 中删除 selectedItem

标签 c# wpf mvvm binding listboxitem

我想在遵守 MVVM 的同时从 ObservableCollection 中删除一个项目。我理解这个任务,我想我很好地理解了逻辑并且已经实现了它,但是该项目从未在 View 中被删除。

我已使用断点跟踪应用程序并且正确读取了 selectedProject 的值。我还添加了变量来检查删除语句前后的集合大小,它们是相同的值,因此它不会删除该项目。我的问题是为什么?我错过了什么?我没有遵守什么规则? .NET 的新手。

**我正在使用 WCF 服务,从我的 CodeFirst 数据库返回项目的 ObservableCollection,一旦用户打开项目 View ,就会调用它。

查看

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

View 模型

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);
            }
        } 

最佳答案

您需要为 SelectedItem 属性进行双向绑定(bind)。

查看

    <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();
    }
}

关于c# - 使用 MVVM 从 ObservableCollection 中删除 selectedItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40810261/

相关文章:

c# - 将对象从部分 View 传递到 Controller

c# - HttpWebRequest.BeginGetResponse

c# - 如何根据按钮点击设置Label的内容

c# - 如何判断是鼠标选中还是按键选中?

mvvm - 将 mvvm light Relay 命令绑定(bind)到页面加载事件

c# - 如何防止使用 PayPal 的网站支付标准编辑隐藏字段?

c# - 找不到相同项目的命名空间

c# - 在构造类的新实例时,如何避免传递对父对象的引用?

c# - 以编程方式将 TextBlock 添加到 DataTemplate

wpf - 在DataGrid列中设置DatePicker的默认值