从带有复选框的列表框中获取选定的项目

Get selected items from a list box with check boxes

A 有一个带复选框的列表框(我删除了与案例无关的关于对齐、宽度、边距的部分):

<ListBox  
ItemsSource ="{Binding SItemCollection}"     
<ListBox.ItemTemplate>
    <DataTemplate>
        <CheckBox Content="{Binding Path=Item.Code}" IsChecked="{Binding IsChecked}"/>
    </DataTemplate>
</ListBox.ItemTemplate>

我的 ViewModel 中有一个 class SItem,它存储两个字段 - 我从缓存中获取的 CachedStr 和一个布尔值 IsChecked,它表示该项目是否被选中(CachedStr 对象也有几个字段(姓名、代码等),我选择显示代码):

public class SItem : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public CachedStr Item { get; set; }
        private bool _isChecked;
        public bool IsChecked
        {
            get { return _isChecked; }
            set
            {
                _isChecked = value;
                NotifyPropertyChanged("IsChecked");
            }
        }

        protected void NotifyPropertyChanged(string strPropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
        }

A 有一个 SItem 集合 (SItemCollection),它用项目填充我的列表框,其中一些已打勾。这个集合在 SItem class 之外,它在我的视图模型中。我还有一组应该在列表框中可用的所有项目 (AvailableSItems) 和一组应该在一开始就检查的项目 (ItemsToBeTicked)。这两个集合包含 CachedStr 类型的对象。通过使用这些集合,我得到了我的 SItemCollection:

public ObservableCollectionEx<SItem> SItemCollection
    {
        get
        {
            ObservableCollectionEx<SItem> strItems = new ObservableCollectionEx<SItem>();
            this.AvailableSItems.ForEach(p =>
            {
                SItem item = new SItem();
                item.Item = p;
                item.IsChecked = false;
                strItems.Add(item);
            });

            strItems.ForEach(p =>
             {
                 if (this.ItemsToBeTicked.Contains(p.Item))
                 {
                     p.IsChecked = true;
                 }
                 else p.IsChecked = false;
             }
             );
            return strItems;
        }
    }

上述代码有效。但我还需要一种方法来获取所有勾选项目的最终集合(例如,在按下按钮之后),这就是我遇到的问题。当我勾选或取消勾选某些内容时,我确实会收到通知。

代码当前在 get 块中创建集合的新实例。这必须更改,否则每次调用 get 块时都会还原 UI 中所做的更改。

获取当前在 get 块中的代码,将其提取到一个方法中并使用该方法的 return 值来设置您的 SItemCollection 属性.

例如在构造函数中:

SItemCollection = CreateInitialCollection();

而 属性 将被简化为:

public ObservableCollectionEx<SItem> SItemCollection 
{
    get
    {
        return _sitemCollection;
    }
    set
    {
        if (_sitemCollection!= value)
        {
            _sitemCollection= value;
            RaisePropertyChanged("SItemCollection");
        }
    }
}
ObservableCollectionEx<SItem> _sitemCollection;

修复后(如果绑定到 SItem 中的 IsChecked 属性 有效),您可以使用 Linq 表达式:

var checkedItems = SItemCollection.Where(item => item.IsChecked == true)