如何将ObservableCollection 绑定到WPF中的Checkbox的Listbox

让我用这个问题作为前缀,说明我对C#和WPF都很新。

我正在尝试将一组Boolean值连接到一个包含6个复选框的容器,并在按下按钮时存储这些值的状态。 我假设有一种简单的方法可以做到这一点,因为将复选框绑定到一个集合似乎是一件非常自然的事情,但到目前为止我看到的所有解决方案看起来都过于复杂(例如: http:// merill。 net / 2009/10 / wpf-checked-listbox / )。

我通过修改ListBox的数据模板创建复选框,并将ListBoxItemsSource设置为ObservableCollection ,但我的问题是我不知道将IsChecked绑定到什么,因为我试图将它绑定到集合中的实际对象,而不是对象的属性。

使用IsChecked="{Binding}"直接绑定集合的项目。

        

但是,使用此方法无法绑定到源。 因为CheckBoxIsChecked属性上的绑定不是绑定项的索引。 因此,它不能更改集合,只能更改集合的项目。

更新

要绕过该限制,您可以创建布尔值的包装器:

 public class Wrapper : INotifyPropertyChanged { private T value; public T Value { get { return value; } set { { this.value = value; OnPropertyChanged(); } } } public static implicit operator Wrapper(T value) { return new Wrapper { value = value }; } public static implicit operator T(Wrapper wrapper) { return wrapper.value; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } 

这是一个例子:

 public partial class MainWindow : Window { public ObservableCollection> MyBooleanCollection { get; private set; } public MainWindow() { InitializeComponent(); DataContext = this; MyBooleanCollection = new ObservableCollection>() { false, true, true, false, true }; } } 

而在XAML中:

  

ItemTemplate你可以写

  

要么

  

它直接绑定到item对象,即集合中的bool值。


但请注意,在任何一种情况下,选中或取消选中CheckBox时,不会替换集合中的绑定值。 为了在单击CheckBox时立即更新集合,您的集合必须包含具有与IsChecked绑定的布尔属性的对象。

在您的情况下,这可能就像下面一样简单(因为您的问题听起来像您不需要属性更改通知):

 public class BooleanHelper { public bool Value { get; set; } } 

绑定现在看起来像这样:

  

该集合现在将是一个ObservableCollection ,您可能会添加如下项目:

 Items.Add(new BooleanHelper { Value = true }); 

通过您提供的链接,您还可以对CheckedListItem类使用INotifyPropertyChanged扩展,但如果您不想使用ObservableCollection。 它会是这样的:

 public class CheckedListItem : INotifyPropertyChanged { private int _Id; public int Id { get; set; NotifyIfAnythingChanged("Id"); } private string _Name; public string Name { get; set; NotifyIfAnythingChanged("Name"); } private bool _IsChecked; public bool IsChecked { get; set; NotifyIfAnythingChanged("IsChecked"); } private void NotifyIfAnythingChanged(String propName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propName)); } public event PropertyChangedEventHandler PropertyChanged; } 

你的列表框应该是这样的:

        

在您的代码中,您应该只初始化ObservableCollection一次,因为对其进行的每个更改都将导致UI更新。

 ObservableCollection MyList = new ObservableCollection(); MyListBox.ItemsSource = MyList; 

现在,对MyList进行的每个更改,例如Add(),Remove()等都会影响您的UI。