【问题标题】:How can I clear a listbox's selected item via binding如何通过绑定清除列表框的选定项
【发布时间】:2013-01-17 18:59:10
【问题描述】:

我有一个 WPF ListBox 通过ItemsSource 绑定到一个集合。 选中的项目以双向模式绑定到 VM 上的属性。 当我为集合中不存在的模型属性分配值时,我希望在 UI 上“取消选择”所选项目。

这可能吗?如果没有,是否有其他方法可以清除所选项目?

请记住,我正在使用 MVVM 模式,因此我无法从代码中访问列表本身。

谢谢!

【问题讨论】:

    标签: wpf mvvm listbox selection itemscontrol


    【解决方案1】:

    我将假设以下内容:

    1. 列表框的 ItemsSource 属性绑定到 ViewModel 中的某个列表(即 VM_List)。
    2. 列表框的 SelectedItem 属性通过 TwoWay 绑定绑定到 ViewModel 中的某个属性(即 VM_SelectedItem)。

    如果以上内容不准确,请提供更多关于您的实施的信息。

    你的视图模型应该有一些看起来像这样的代码:

    public class VM : INotifyPropertyChanged
    {
        private ObservableCollection<Student> vmlist = new ObservableCollection<Student>();
        private Student vmselecteditem;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public VM()
        {
            PropertyChanged = new PropertyChangedEventHandler(VM_PropertyChanged);
        }
    
        private void VM_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
        }
    
        public ObservableCollection<Student> VM_List
        {
            get
            {
                return vmlist;
            }
        }
    
        public Student VM_SelectedItem
        {
            get
            {
                return vmselecteditem;
            }
            set
            {
                vmselecteditem = value;
            }
        }
    
        public void AddNewStudent(Student NewStudent)
        {
            VM_SelectedItem = null;
            PropertyChanged(this, new PropertyChangedEventArgs("VM_SelectedItem"));
            VM_SelectedItem = NewStudent;
            SaveStudent();
            PropertyChanged(this, new PropertyChangedEventArgs("VM_SelectedItem"));
            //The last line is optional, if you want to select the new student just added.
        }
    
        private void SaveStudent()
        {
            //A fake operation to save the student.
            //To stick with MVVM, the save function should be in the model
            //And this function should just call the one in the model.
            BackgroundWorker b = new BackgroundWorker();
            b.DoWork += new DoWorkEventHandler(b_DoWork);
            b.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
            b.RunWorkerAsync();
        }
    
        private void AddStudentToList()
        {
            VM_List.Add(VM_SelectedItem);
        }
    
        private void b_DoWork(object sender, DoWorkEventArgs e)
        {
            //Simulating a long save operation
            System.Threading.Thread.Sleep(2000);
        }
    
        private void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            AddStudentToList();
        }
    }
    

    【讨论】:

    • 您所做的两个假设是正确的。我忘了提到的是,我也将 vmselecteditem 属性用于其他目的。即使它不是收藏的一部分,我也需要它具有价值。感谢您的回答!
    • 这很有趣......在这种情况下,将其设置为 null 并不是一个真正的选择。您可能需要考虑使用 UI 绑定的第二个属性来“选择项目”,例如 VM_SelectedItem_UI 属性。 VM_SelectedItem_UI 当且仅当它是集合的一部分时才会更新 VM_SelectedItem,反之亦然。我真的想不出更好的方法来做到这一点。如果您需要澄清,我可以发布一些代码。
    • 谢谢!我理解解决方案,但对于我相当简单的要求来说,这听起来有点太复杂了。由于我缺乏 mvvm 经验,我的设计中可能有问题。我有一个学生列表和一个绑定到选定学生属性的学生数据模板。当我选择一个列表框项目时,它绑定到同一个选定的学生,然后根据新选择的学生更改数据模板。我的问题中的用例是当我想添加一个新学生,然后我需要它成为一个新实例,这显然不是学生列表的一部分。我错过了什么吗?
    • 嗯,如果我理解正确,您想在将新的学生实例添加到列表之前清除所选项目吗?使用我提供的示例,您可以在 ViewModel 中有一个函数,它 1) 取消选择当前选定的项目,2) 将新学生添加到列表中,以及 3) 如果需要,您可以选择刚刚添加的新学生.我已经更新了我的答案以反映这一点。很抱歉,如果这不是您的意思,有时很难通过互联网访问同一页面。
    • 感谢您的努力!这不是我想要的:] 在保存之前,我不希望将新学生添加到列表中。我希望新学生被选定的属性引用,而不是学生列表的一部分。正如我之前所说,虽然是这种情况,但应该清除列表中的选择
    猜你喜欢
    • 2014-07-31
    • 1970-01-01
    • 2020-12-29
    • 2012-04-01
    • 2022-10-20
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多