XAML Developer Chips: Embedded Converters
- Tutorial
Let's analyze an interesting and non-standard scenario for using converters - Inline Converter .
Probably, some developers were faced with the problem that when using converters, information about the presentation, its data context or the visual element to which the binding is performed is not transferred to the converter parameters. On the one hand, it’s good, it turns out that there is some protection and separation of logic, it’s not too right to work directly with the control in the converter, but on the other hand, in rare cases, it’s because of such a limitation that you have to go to various tricks.
The good old event model is still not lost its relevance even though that was developed powerful and efficient data binding mechanism ( the Data the Binding) Of course, you should not use events to the detriment of progressive development tools, but sometimes their application turns out to be convenient and natural.
Why not combine both of these methods? For example, in this way
What do we get? We need to embed the converter instance in the control or presentation resources, and in the Behind code ( Code Behind ) of the presentation, make the necessary handlers for the Converting and ConvertingBack events , after which these events will be called during the binding operation, and in the handlers this pointer will be available as itself view with visual tree, and data context! Suddenly, I got a lot of freedom of action, and besides, everything remained ideologically true, because the interface logic did not get into the converter itself, and it remained only in the behin code.
Here is a simple example of using this approach
The additional use of the Composite Converter [ ICompositeConverter ] pattern allows you to combine various converters into chains, modifying the logic, without the need to create new classes.
You can see Inline Converter and some others in action in the HelloAero demo project of the Aero Framework library [ backup link ].
Thank you for attention!
PS Previous article on Dynamic Grid
Update
Application
The need for the presented method in practice arises infrequently, but at the same time it can make life extremely difficult in “uncomfortable” situations. For example, this way you can replace MultiBinding when porting code from WPF to Windows Phone , since multiple binding is not supported on the mobile platform. Just remember the built-in converters and at the right time you will find application for them.
Probably, some developers were faced with the problem that when using converters, information about the presentation, its data context or the visual element to which the binding is performed is not transferred to the converter parameters. On the one hand, it’s good, it turns out that there is some protection and separation of logic, it’s not too right to work directly with the control in the converter, but on the other hand, in rare cases, it’s because of such a limitation that you have to go to various tricks.
The good old event model is still not lost its relevance even though that was developed powerful and efficient data binding mechanism ( the Data the Binding) Of course, you should not use events to the detriment of progressive development tools, but sometimes their application turns out to be convenient and natural.
Why not combine both of these methods? For example, in this way
ICompositeConverter
using System.Windows.Data;
namespace Aero.Converters.Patterns
{
public interface ICompositeConverter : IValueConverter
{
IValueConverter PostConverter { get; set; }
object PostConverterParameter { get; set; }
}
}
IInlineConverter
using System;
using System.Globalization;
using System.Windows.Data;
namespace Aero.Converters.Patterns
{
public class ConverterEventArgs : EventArgs
{
public object ConvertedValue { get; set; }
public object Value { get; private set; }
public Type TargetType { get; private set; }
public object Parameter { get; private set; }
public CultureInfo Culture { get; private set; }
public ConverterEventArgs(object value, Type targetType, object parameter, CultureInfo culture)
{
TargetType = targetType;
Parameter = parameter;
Culture = culture;
Value = value;
}
}
public interface IInlineConverter : IValueConverter
{
event EventHandler Converting;
event EventHandler ConvertingBack;
}
//public interface IInlineConverter : IValueConverter
//{
// event Func
Inlineconverter
using System;
using System.Globalization;
using System.Windows.Data;
using Aero.Converters.Patterns;
namespace Aero.Converters
{
public class InlineConverter : IInlineConverter, ICompositeConverter
{
public IValueConverter PostConverter { get; set; }
public object PostConverterParameter { get; set; }
public event EventHandler Converting;
public event EventHandler ConvertingBack;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var args = new ConverterEventArgs(value, targetType, parameter, culture);
var handler = Converting;
if (handler != null) handler(this, args);
return PostConverter == null
? args.ConvertedValue
: PostConverter.Convert(args.ConvertedValue, targetType, PostConverterParameter, culture);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var args = new ConverterEventArgs(value, targetType, parameter, culture);
var handler = ConvertingBack;
if (handler != null) handler(this, args);
return PostConverter == null
? args.ConvertedValue
: PostConverter.ConvertBack(args.ConvertedValue, targetType, PostConverterParameter, culture);
}
}
}
What do we get? We need to embed the converter instance in the control or presentation resources, and in the Behind code ( Code Behind ) of the presentation, make the necessary handlers for the Converting and ConvertingBack events , after which these events will be called during the binding operation, and in the handlers this pointer will be available as itself view with visual tree, and data context! Suddenly, I got a lot of freedom of action, and besides, everything remained ideologically true, because the interface logic did not get into the converter itself, and it remained only in the behin code.
Here is a simple example of using this approach
private void InlineConverter_OnConverting(object sender, ConverterEventArgs e)
{
e.ConvertedValue =
string.Format("Title: {0} \nDataContext:\n{1} \nConverter Value: {2}",
Title,
DataContext,
e.Value);
}
The additional use of the Composite Converter [ ICompositeConverter ] pattern allows you to combine various converters into chains, modifying the logic, without the need to create new classes.
You can see Inline Converter and some others in action in the HelloAero demo project of the Aero Framework library [ backup link ].
Thank you for attention!
PS Previous article on Dynamic Grid
Update
Application
The need for the presented method in practice arises infrequently, but at the same time it can make life extremely difficult in “uncomfortable” situations. For example, this way you can replace MultiBinding when porting code from WPF to Windows Phone , since multiple binding is not supported on the mobile platform. Just remember the built-in converters and at the right time you will find application for them.