WPF CheckBox TwoWay Binding not working
You need to raise the PropertyChanged
event when you set Foo in your DataContext
. Normally, it would look something like:
public class ViewModel : INotifyPropertyChanged{ private bool _foo; public bool Foo { get { return _foo; } set { _foo = value; OnPropertyChanged("Foo"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }}
If you call Foo = someNewvalue
, the PropertyChanged
event will be raised and your UI should be updated
I spent hours looking for a complete answer to this issue. I guess some people assume that other people searching this issue know the basics - sometimes we don't. A very important part about setting the form's data context was usually missing:
public YourFormConstructor() { InitializeComponent(); DataContext = this; // <-- critical!! }
My checkbox control was set up in the xaml file like this:
<CheckBox x:Name="chkSelectAll" IsChecked="{Binding chkSelectAllProp, Mode=TwoWay}" HorizontalAlignment="Left"/>
The "Path=" and "UpdateSourceTrigger=..." parts appear to be optional, so I left them out.
I am using this checkbox in a ListView header column. When someone checks or unchecks the checkbox, I want all the items in the ListView to also be checked or unchecked (select/unselect all functionality). I left that code in the example (as "optional logic") but your checkbox value logic (if any) would replace this.
The ListView contents are set by browsing for a file, and when a new file is selected, code sets the ListView ItemsSource and the CheckBox is checked (selecting all the new ListView items), which is why this two-way operation is required. That portion of the code is not present in this example.
The code in the xaml.cs file to handle the CheckBox looks like this:
// backing value private bool chkSelectAllVal; // property interchange public bool chkSelectAllProp { get { return chkSelectAllVal; } set { // if not changed, return if (value == chkSelectAllVal) { return; } // optional logic if (value) { listViewLocations.SelectAll(); } else { listViewLocations.UnselectAll(); } // end optional logic // set backing value chkSelectAllVal = value; // notify control of change OnPropertyChanged("chkSelectAllProp"); } } // object to handle raising event public event PropertyChangedEventHandler PropertyChanged; // Create the OnPropertyChanged method to raise the event protected void OnPropertyChanged(string name) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }