So I am learning WPF right now, and want to do a simple databind between a bool value, and whether or not a MenuItem
is enabled or not.
I have coded it like this:
<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click"
IsEnabled="{Binding}" />
And in the .cs file I set:
miSaveFile.DataContext = dataChanged;
For some reason the MenuItem
doesn't seem to be properly reflecting the state of dataChanged.
What am I missing?
You are better off binding to an object than to a primitive type. This object is often referred to as the "model" for your view.
WPF uses the INotifyPropertyChanged interface for the model (or often view-model) to notify the view that the model has changed states.
So you will first want to define a data class as the model that implements the INotifyPropertyChanged interface and fires the PropertyChanged event whenever a property is changed.
When you set a binding, you have 5 main elements on the binding to worry about. The binding has a source object, a source path on the source object, a target object, a target property on the target object, and an optional converter.
If you do not specify the source, it defaults to the DataContext of the control the binding is set on. There are other options for setting the source. Here is a Microsoft article on setting the source. You can then set the path of a property to pull out of the source for the binding. In your case, the source is a boolean and there is no path because the binding is using the whole source object.
The target is always the control that you set the binding on, and the target property is the property on this control that you are binding to. In this case, MenuItem and IsEnabled.
A converter can optionally convert the source value into a value that is compatible with the target property. You can use any object for a converter that implements IValueConverter or IMultiValueConverter (for MutliBindings).
In your case, I would first create a model that implements INotifyPropertyChanged. Next, I would assign the DataContext of the menu to an instance of the model. Then I would set the binding to:
IsEnabled="{Binding Path=EnableFlag}"
(Where EnableFlag is a boolean property in the model that you want to menu to bind to)
If you set up the INotifyPropertyChanged interface correctly, the menu item will be enabled/disabled whenever you change this property on the model.