Bind a control to a single value in a collection / array in WPF

In WPF, do I have a bool collection? values, and I want to associate each of them with separate software. I want the bindings to be TwoWay, so changing the value of an individual item in a collection in code updates the checkbox and vice versa.

I spent years trying to figure out how to do this, and I was completely stuck. In the following code, the checkbox only gets the correct value when the window is loaded and what it is. Changing the checkbox does not even update the value in the collection. (UPDATE: this seems to be a bug in .NET4, because the collection is being updated in one .NET3.5 project. UPDATE: Microsoft has confirmed the bug and that it will be fixed in the .NET4 release.)

Thank you very much for your help!

FROM#:

namespace MyNamespace { public partial class MyWindow : Window, INotifyPropertyChanged { public MyWindow() { InitializeComponent(); DataContext = this; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public List<bool?> myCollection = new List<bool?> { true, false, true, false, true, false }; public List<bool?> MyCollection { get { return myCollection; } set { myCollection = value; } } } } 

XAML:

 <CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}"> 
+4
source share
3 answers

There are a few things you need to change here to make this work. First, you will need to wrap your boolean in an object that implements the INotifyPropertyChanged interface to receive a notification of the change you are looking for. You are currently bound to booleans in your collection that do not implement the interface. To do this, you can create a wrapper class as follows:

  public class Wrapper: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private bool val = false; public bool Val { get { return val; } set { val = value; this.OnPropertyChanged("Val"); } } public Wrapper(bool val) { this.val = val; } } 

Then you want to create these objects in your form instead of a list of gates. You can also use an observable collection instead of a list to send notification of added and deleted items. This is shown below:

 public Window1() { InitializeComponent(); this.DataContext = this; } private ObservableCollection<Wrapper> myCollection = new ObservableCollection<Wrapper>() {new Wrapper(true), new Wrapper(false), new Wrapper(true)}; public ObservableCollection<Wrapper> MyCollection { get { return myCollection; } } 

The next thing to do is show a list of checkboxes in your ui. For this, WPF provides itemscontrols functions. ListBox is a control for items, so we can use this as a starting point. Set itemssource in the list as MyCollection. Then we need to determine how each Wrapper object will appear in the list, and this can be done using the datatemplate that is created in the Windows resources. This is shown below:

 <Window.Resources> <DataTemplate x:Key="myCollectionItems"> <CheckBox IsChecked="{Binding Path=Val, Mode=TwoWay}"></CheckBox> </DataTemplate> </Window.Resources> <Grid> <ListBox ItemsSource="{Binding Path=MyCollection}" ItemTemplate="{StaticResource myCollectionItems}"></ListBox> </Grid> 

This should make you work with a simple demonstration of checkboxes that have values ​​tied to a list of gates.

+5
source

Change List<bool?> To ObservableCollection<bool?> . The list does not display notification of changes that WPF should update. The observed collection does. This handles the case when the list entry changes and the CheckBox needs to be updated accordingly.

In the other direction, it works for me even with List<bool?> - that is, when the flag is switched, the value in the collection changes. Your binding syntax is definitely correct.

+1
source

Why do you think that it does not work? This works for me :)

Here is my XAML test:

 <UniformGrid> <CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}"/> <ListBox ItemsSource="{Binding MyCollection}"/> <Button Content="Test" Click="Button_Click"/> </UniformGrid> 

Here is my code:

 private void Button_Click(object sender, RoutedEventArgs e) { } 

(the rest is the same as yours)

I set a breakpoint on Button_Click and checked MyCollection[0] , it was updated according to IsChecked value of CheckBox .

Try changing the type of the collection from List<bool?> To ObservableCollection<bool?> , Perhaps for this reason you think this does not work for you (the fact that changes to the collection are not reflected anywhere in your view).

0
source

All Articles