Blue Flower

Let us examine an interesting and non-standard usage scenario of converters Inline Converter.
image
Likely, some developers are faced with the problem that when using converters in the converter options are not transmitted information on the representation of its data context or the visual element, which carried out the binding. On the one hand it is good, get some protection and separation of logic, not too well in the converter to work directly with the control, on the other hand, in rare cases it is because of this restriction 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 (Data Binding). Of course, it is not necessary to use the events to the detriment of progressive development tools, but sometimes their application turns convenient and natural.

Why not combine both methods? For example, thus

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 Converting;
    //    event Func ConvertingBack;
    //}
}


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? converter instance, we need to insert in the control of resources or view and behain code (Code Behind) representation to make the necessary handlers for events Converting and ConvertingBack, after which the event will be called during the operation bindings and handlers through a pointer this will be available as a matter c visual representation of a tree, and data context! Suddenly I get a lot of freedom of action, besides everything remains ideologically correct, because he has not got the converter interface logic, and it was only in behain code.

Here is a simple example of using this approach

<Grid>
    <Grid.Resources>
        <InlineConverter x:Key="InlineConverter" Converting="InlineConverter_OnConverting"/>
    </Grid.Resources>
    <TextBlock Text="{Binding Number, Converter={StaticResource InlineConverter}}"/>
</Grid>

        private void InlineConverter_OnConverting(object sender, ConverterEventArgs e)
        {
            e.ConvertedValue =
                string.Format("Title: {0} \nDataContext:\n{1} \nConverter Value: {2}",
                    Title,
                    DataContext,
                    e.Value);
        }

Additional use pattern Composite Converter allows you to combine a variety of converters in the chain by modifying the logic, without having to create new classes.

See it in action Inline Converter and some others may be in the demonstration project HelloAero library Aero Framework [backup link].

Thank you for attention!

P.S. Dynamic Grid

Update
Using
НNecessity in the present method, in practice there is rarely, but at the same time it can make life easier in the very "uncomfortable" situations. For example, this way you can replace MultiBinding when porting code from the WPF to Windows Phone, since multiple binding is not supported on the mobile platform. Just remember embedded converters and at the right time you will find applications for them.