ValueConverters
Introduction
If you want to databind two properties that have incompatible types, you need a piece of code in between, that converts the value from source to target type and back. This piece of code is called ValueConverter. A value converter is a class, that implements the simple interface IValueConverter with the two methods object Convert(object value) and object ConvertBack(object value) .
How to implement a ValueConverter
WPF already provides a few value converts, but you will soon need to implement your own converts. To do this, add a class to your project and call it [SourceType]To[TargetType]Converter . This is a common naming for value converters. Make it public and implement the IValueConverter interface. That's all you need to do.
How to use a ValueConverter in XAML
First thing you need to do is to map the namespace of your converter to a XAML namespace. Then you can create an instance of a value converter in the resources of the view and give it a name. Then you can reference it by using
Simplify the usage of ValueConvers
If you want to use a normal ValueConverter in XAML, you have to add an instance of it to the resources and reference it by using a key. This is cumbersome, because and the key is typically just the name of the converter.
A simple and cool trick is to derive value converters from MarkupExtension . This way you can create and use it in the binding like this: Text=> , and that is quite cool!
Wpf value converter property changed
Get via App Store Read this post in our app!
Converter with Dependency Properties
I have problems implementing a custom DependencyObject:
I need a converter which sets or unsets a enum flag in a bound property. Therefore I created a IValueConverter derieved from FrameworkElement with two DependencyProperties: Flag (the flag which is set/unset by the converter) and Flags (the value/property to modify). The parent UserControl (Name = EnumerationEditor) provides the property to which the converter is bound.
A ListBox generates CheckBoxes and the converter instances which are used to modify the property via a DataTemplate. Each CheckBox/converter instance is used for one flag. I use the following XAML code:
The strange thing: The Label works fine - but the converter does not. I get the error:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=EnumerationEditor'. BindingExpression:Path=Value; DataItem=null; target element is 'EnumerationConverter' (Name=''); target property is 'Flags' (type 'Enum')
I don't understand why, the binding is basically the same.
Here is the code for the converter:
A converter is not a FrameworkElement so it should not inherit from that class, at best use DependencyObject .
Since the converter is not in any tree that binding will not work, you can try:
(However this should be placed in the Resources of the UserControl and referenced, otherwise the x:Reference will cause a cyclical dependency error.)
Note that the Flag binding tries to bind to the DataContext which might not work as the DataContext may not be inherited for the same reasons that ElementName and RelativeSource will not work.
I decided to solve the problem using two UserControls; FlagControl and EnumerationEditorControl.
The FlagControl has two dependency properties
- Flag (System.Enum): Determines which flag is set/cleared by the control
- Value(System.Enum): Bound to the propery/value in which the flag is set/cleared.
The EnumerationEditorControl has one dependency property:
- Value(System.Enum): The propery/value in which flags are set.
The EnumerationEditorControl uses a DataTemplate to instantiate FlagControls. The DataTemplate binds the FlagControl.Flag property to the DataContext and the FlagControl.Value property to the EnumerationEditorControl.Value property.
This way I don't need a converter and logic is clearly separated.
Thanks for the suggestions, comments and replies!
Wpf value converter property changed
Get via App Store Read this post in our app!
INotifyPropertyChanged does not update Value Converter
I have some properties which implement the INotifyPropertyChanged interface. It works fine. But in my code I also use some value converters (if value < 3 - make grid red, if value >3 and value < 10 - make grid blue, etc.).
The problem is how to refresh value converter after PropertyChanged was raised? Is there simple code behind solution? Thanks all and sorry for my bad English!
And here I apply my value converter to the grid:
If you have done it "correctly" the PropertyChanged event will cause an update of the bindings which bind to that property, when this occurs any converters that are used in the same binding will reconvert the values. So normally the conversions happen on their own. If this is not the case you are probably using the converters "inappropriately", please post some code because without it it's quite impossible to tell what exactly you are doing wrong.
Edit: You use grid.SetValue(Grid.BackgroundProperty, bin) , you should use grid.SetBinding(Grid.BackgroundProperty, bin) instead since it is a binding.
Edit2: This really has nothing to do with converters.
In your sample code you bind to IntValue , then you change TodayColor and expect the binding to be updated, not gonna happen. If you want the binding to react to both properties you have to either use a MultiBinding or raise the respective events since your properties are interdependent.