|
|
|
|
using System.Globalization;
|
|
|
|
|
|
|
|
|
|
namespace Connected;
|
|
|
|
|
|
|
|
|
|
public class Converter<TSourceType, TDestinationType>
|
|
|
|
|
{
|
|
|
|
|
public event EventHandler<string?>? ErrorOccured;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The culture info being used for decimal points, date and time format, etc.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public CultureInfo Culture { get; set; } = Converters.DefaultCulture;
|
|
|
|
|
|
|
|
|
|
public TDestinationType? Convert(TSourceType value)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return ConvertValue(value);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
TriggerError($"Conversion from {typeof(TSourceType).Name} to {typeof(TDestinationType).Name} failed: {e.Message}", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual TDestinationType? ConvertValue(TSourceType? value)
|
|
|
|
|
{
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TSourceType? ConvertBack(TDestinationType value)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return ConvertValueBack(value);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
TriggerError($"Conversion from {typeof(TDestinationType).Name} to {typeof(TSourceType).Name} failed: {e.Message}", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual TSourceType? ConvertValueBack(TDestinationType? value)
|
|
|
|
|
{
|
|
|
|
|
return default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void TriggerError(string? msg, Exception? e = null)
|
|
|
|
|
{
|
|
|
|
|
ErrorOccured?.Invoke(this, msg);
|
|
|
|
|
|
|
|
|
|
OnErrorOccured(msg, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void OnErrorOccured(string? msg, Exception? e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Converts values using the supplied lambda functions.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TSourceType">The source type</typeparam>
|
|
|
|
|
/// <typeparam name="TDestinationType">The destination type</typeparam>
|
|
|
|
|
public class LambdaConverter<TSourceType, TDestinationType> :Converter<TSourceType, TDestinationType>
|
|
|
|
|
{
|
|
|
|
|
private readonly Func<TSourceType, TDestinationType?>? _convertFunction;
|
|
|
|
|
private readonly Func<TDestinationType, TSourceType?>? _convertBackFunction;
|
|
|
|
|
|
|
|
|
|
public LambdaConverter(Func<TSourceType, TDestinationType?>? convertFunction = null, Func<TDestinationType, TSourceType?>? convertBackFunction = null)
|
|
|
|
|
{
|
|
|
|
|
_convertFunction = convertFunction;
|
|
|
|
|
_convertBackFunction = convertBackFunction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override TDestinationType? ConvertValue(TSourceType? value)
|
|
|
|
|
{
|
|
|
|
|
if (_convertFunction is null)
|
|
|
|
|
return base.ConvertValue(value);
|
|
|
|
|
|
|
|
|
|
return _convertFunction.Invoke(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override TSourceType? ConvertValueBack(TDestinationType? value)
|
|
|
|
|
{
|
|
|
|
|
if (_convertFunction is null)
|
|
|
|
|
return base.ConvertValueBack(value);
|
|
|
|
|
|
|
|
|
|
return _convertBackFunction.Invoke(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Converter from T to string
|
|
|
|
|
///
|
|
|
|
|
/// Set converts to string
|
|
|
|
|
/// Get converts from string
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ToStringConverter<T> : Converter<T, string>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Custom Format to be applied on bidirectional way.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string? Format { get; set; } = null;
|
|
|
|
|
}
|