[WIP] Refactor default converters

pull/2/head
Matija Koželj 2 years ago
parent 82594cff34
commit 2daf5b6c1e

@ -11,11 +11,19 @@ namespace Connected
public BoolConverter() public BoolConverter()
{ {
SetFunc = OnSet;
GetFunc = OnGet;
} }
private T OnGet(bool? value) protected override bool? ConvertValue(T? value)
{
return OnSet(value);
}
protected override T? ConvertValueBack(bool? value)
{
return OnGet(value);
}
private T OnGet(bool? value)
{ {
try try
{ {
@ -31,12 +39,12 @@ namespace Connected
return (T)(object)(value == true ? 1 : (value == false ? (int?)0 : null)); return (T)(object)(value == true ? 1 : (value == false ? (int?)0 : null));
else else
{ {
UpdateGetError($"Conversion to type {typeof(T)} not implemented"); TriggerError($"Conversion to type {typeof(T)} not implemented");
} }
} }
catch (Exception e) catch (Exception e)
{ {
UpdateGetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
return default(T); return default(T);
} }
return default(T); return default(T);
@ -69,13 +77,13 @@ namespace Connected
} }
else else
{ {
UpdateSetError("Unable to convert to bool? from type " + typeof(T).Name); TriggerError("Unable to convert to bool? from type " + typeof(T).Name);
return null; return null;
} }
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateSetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
return null; return null;
} }
} }

@ -1,88 +1,111 @@
using System; using System.Globalization;
using System.Globalization;
namespace Connected namespace Connected;
{
public class Converter<T, U>
{
public Func<T, U> SetFunc { get; set; }
public Func<U, T> GetFunc { get; set; }
/// <summary> public class Converter<TSourceType, TDestinationType>
/// The culture info being used for decimal points, date and time format, etc. {
/// </summary> public event EventHandler<string?>? ErrorOccured;
public CultureInfo Culture { get; set; } = Converters.DefaultCulture;
public Action<string> OnError { get; set; } /// <summary>
public bool SetError { get; set; } /// The culture info being used for decimal points, date and time format, etc.
public bool GetError { get; set; } /// </summary>
public string SetErrorMessage { get; set; } public CultureInfo Culture { get; set; } = Converters.DefaultCulture;
public string GetErrorMessage { get; set; }
public U Set(T value) public TDestinationType? Convert(TSourceType value)
{
try
{ {
SetError = false; return ConvertValue(value);
SetErrorMessage = null;
if (SetFunc == null)
return default(U);
try
{
return SetFunc(value);
}
catch (Exception e)
{
SetError = true;
SetErrorMessage = $"Conversion from {typeof(T).Name} to {typeof(U).Name} failed: {e.Message}";
}
return default(U);
} }
catch (Exception e)
public T Get(U value)
{ {
GetError = false; TriggerError($"Conversion from {typeof(TSourceType).Name} to {typeof(TDestinationType).Name} failed: {e.Message}", e);
GetErrorMessage = null;
if (GetFunc == null)
return default(T);
try
{
return GetFunc(value);
}
catch (Exception e)
{
GetError = true;
GetErrorMessage = $"Conversion from {typeof(U).Name} to {typeof(T).Name} failed: {e.Message}";
}
return default(T);
} }
protected void UpdateSetError(string msg) return default;
}
protected virtual TDestinationType? ConvertValue(TSourceType? value)
{
return default;
}
public TSourceType? ConvertBack(TDestinationType value)
{
try
{ {
SetError = true; return ConvertValueBack(value);
SetErrorMessage = msg;
OnError?.Invoke(msg);
} }
catch (Exception e)
protected void UpdateGetError(string msg)
{ {
GetError = true; TriggerError($"Conversion from {typeof(TDestinationType).Name} to {typeof(TSourceType).Name} failed: {e.Message}", e);
GetErrorMessage = msg;
OnError?.Invoke(msg);
} }
return default;
} }
/// <summary> protected virtual TSourceType? ConvertValueBack(TDestinationType? value)
/// Converter from T to string
///
/// Set converts to string
/// Get converts from string
/// </summary>
public class Converter<T> : Converter<T, string>
{ {
return default;
}
/// <summary> protected void TriggerError(string? msg, Exception? e = null)
/// Custom Format to be applied on bidirectional way. {
/// </summary> ErrorOccured?.Invoke(this, msg);
public string Format { get; set; } = null;
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;
} }

@ -1,4 +1,5 @@
using System.Globalization; using Connected.Extensions;
using System.Globalization;
namespace Connected namespace Connected
{ {
@ -7,9 +8,8 @@ namespace Connected
public static CultureInfo DefaultCulture = CultureInfo.CurrentUICulture; public static CultureInfo DefaultCulture = CultureInfo.CurrentUICulture;
#region --> Date converters #region --> Date converters
public static Converter<DateTime> IsoDate public static LambdaConverter<DateTime, string> IsoDate
=> new() => new(SetIsoDate, GetIsoDate);
{ SetFunc = SetIsoDate, GetFunc = GetIsoDate };
private static DateTime GetIsoDate(string value) private static DateTime GetIsoDate(string value)
{ {
@ -23,11 +23,10 @@ namespace Connected
return value.ToIsoDateString(); return value.ToIsoDateString();
} }
public static Converter<DateTime?> NullableIsoDate public static LambdaConverter<DateTime?, string?> NullableIsoDate
=> new() => new(SetNullableIsoDate, GetNullableIsoDate);
{ SetFunc = SetNullableIsoDate, GetFunc = GetNullableIsoDate };
private static DateTime? GetNullableIsoDate(string value) private static DateTime? GetNullableIsoDate(string? value)
{ {
if (DateTime.TryParse(value, out var dateTime)) if (DateTime.TryParse(value, out var dateTime))
return dateTime; return dateTime;

@ -6,18 +6,26 @@ namespace Connected
/// <summary> /// <summary>
/// A ready made DateTime? to string binding converter with configurable date format and culture /// A ready made DateTime? to string binding converter with configurable date format and culture
/// </summary> /// </summary>
public class NullableDateConverter : Converter<DateTime?> public class NullableDateConverter : ToStringConverter<DateTime?>
{ {
public string DateFormat { get; set; } public string DateFormat { get; set; }
public NullableDateConverter(string format = "yyyy-MM-dd") public NullableDateConverter(string format = "yyyy-MM-dd")
{ {
DateFormat = format; DateFormat = format;
SetFunc = OnSet;
GetFunc = OnGet;
} }
private DateTime? OnGet(string arg) protected override string? ConvertValue(DateTime? value)
{
return OnSet(value);
}
protected override DateTime? ConvertValueBack(string? value)
{
return OnGet(value);
}
private DateTime? OnGet(string arg)
{ {
try try
{ {
@ -25,7 +33,7 @@ namespace Connected
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateGetError(e.Message); TriggerError(e.Message);
return null; return null;
} }
} }
@ -40,7 +48,7 @@ namespace Connected
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateSetError(e.Message); TriggerError(e.Message);
return null; return null;
} }
} }
@ -49,18 +57,26 @@ namespace Connected
/// <summary> /// <summary>
/// A ready made DateTime to string binding converter with configurable date format and culture /// A ready made DateTime to string binding converter with configurable date format and culture
/// </summary> /// </summary>
public class DateConverter : Converter<DateTime> public class DateConverter : ToStringConverter<DateTime>
{ {
public string DateFormat { get; set; } = "yyyy-MM-dd"; public string DateFormat { get; set; } = "yyyy-MM-dd";
public DateConverter(string format) public DateConverter(string format)
{ {
DateFormat = format; DateFormat = format;
SetFunc = OnSet;
GetFunc = OnGet;
} }
private DateTime OnGet(string arg) protected override string? ConvertValue(DateTime value)
{
return OnSet(value);
}
protected override DateTime ConvertValueBack(string value)
{
return OnGet(value);
}
private DateTime OnGet(string arg)
{ {
try try
{ {
@ -68,7 +84,7 @@ namespace Connected
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateGetError(e.Message); TriggerError(e.Message);
return default; return default;
} }
} }
@ -81,7 +97,7 @@ namespace Connected
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateSetError(e.Message); TriggerError(e.Message);
return null; return null;
} }
} }

@ -7,16 +7,24 @@ namespace Connected
/// <summary> /// <summary>
/// A universal T to string binding converter /// A universal T to string binding converter
/// </summary> /// </summary>
public class DefaultConverter<T> : Converter<T> public class DefaultConverter<T> : ToStringConverter<T>
{ {
public DefaultConverter() public DefaultConverter()
{ {
SetFunc = ConvertToString;
GetFunc = ConvertFromString;
} }
public string DefaultTimeSpanFormat { get; set; } = "c"; protected override string? ConvertValue(T? value)
{
return ConvertToString(value);
}
protected override T? ConvertValueBack(string? value)
{
return ConvertFromString(value);
}
public string DefaultTimeSpanFormat { get; set; } = "c";
protected virtual T ConvertFromString(string value) protected virtual T ConvertFromString(string value)
{ {
@ -42,91 +50,91 @@ namespace Connected
return (T)(object)true; return (T)(object)true;
if (lowerValue is "false" or "off") if (lowerValue is "false" or "off")
return (T)(object)false; return (T)(object)false;
UpdateGetError("Not a valid boolean"); TriggerError("Not a valid boolean");
} }
// sbyte // sbyte
else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?))
{ {
if (sbyte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (sbyte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// byte // byte
else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?))
{ {
if (byte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (byte.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// short // short
else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?))
{ {
if (short.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (short.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// ushort // ushort
else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?))
{ {
if (ushort.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (ushort.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// int // int
else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?))
{ {
if (int.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (int.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// uint // uint
else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?))
{ {
if (uint.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (uint.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// long // long
else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?))
{ {
if (long.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (long.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// ulong // ulong
else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?))
{ {
if (ulong.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue)) if (ulong.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// float // float
else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?))
{ {
if (float.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) if (float.TryParse(value, NumberStyles.Any, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// double // double
else if (typeof(T) == typeof(double) || typeof(T) == typeof(double?)) else if (typeof(T) == typeof(double) || typeof(T) == typeof(double?))
{ {
if (double.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) if (double.TryParse(value, NumberStyles.Any, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// decimal // decimal
else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?))
{ {
if (decimal.TryParse(value, NumberStyles.Any, Culture, out var parsedValue)) if (decimal.TryParse(value, NumberStyles.Any, Culture, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid number"); TriggerError("Not a valid number");
} }
// guid // guid
else if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?)) else if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?))
{ {
if (Guid.TryParse(value, out var parsedValue)) if (Guid.TryParse(value, out var parsedValue))
return (T)(object)parsedValue; return (T)(object)parsedValue;
UpdateGetError("Not a valid GUID"); TriggerError("Not a valid GUID");
} }
// enum // enum
else if (IsNullableEnum(typeof(T))) else if (IsNullableEnum(typeof(T)))
@ -134,13 +142,13 @@ namespace Connected
var enum_type = Nullable.GetUnderlyingType(typeof(T)); var enum_type = Nullable.GetUnderlyingType(typeof(T));
if (Enum.TryParse(enum_type, value, out var parsedValue)) if (Enum.TryParse(enum_type, value, out var parsedValue))
return (T)parsedValue; return (T)parsedValue;
UpdateGetError("Not a value of " + enum_type.Name); TriggerError("Not a value of " + enum_type.Name);
} }
else if (typeof(T).IsEnum) else if (typeof(T).IsEnum)
{ {
if (Enum.TryParse(typeof(T), value, out var parsedValue)) if (Enum.TryParse(typeof(T), value, out var parsedValue))
return (T)parsedValue; return (T)parsedValue;
UpdateGetError("Not a value of " + typeof(T).Name); TriggerError("Not a value of " + typeof(T).Name);
} }
// datetime // datetime
else if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?)) else if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
@ -151,7 +159,7 @@ namespace Connected
} }
catch (FormatException) catch (FormatException)
{ {
UpdateGetError("Not a valid date time"); TriggerError("Not a valid date time");
} }
} }
// timespan // timespan
@ -163,17 +171,17 @@ namespace Connected
} }
catch (FormatException) catch (FormatException)
{ {
UpdateGetError("Not a valid time span"); TriggerError("Not a valid time span");
} }
} }
else else
{ {
UpdateGetError($"Conversion to type {typeof(T)} not implemented"); TriggerError($"Conversion to type {typeof(T)} not implemented");
} }
} }
catch (Exception e) catch (Exception e)
{ {
UpdateGetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
} }
return default(T); return default(T);
@ -301,7 +309,7 @@ namespace Connected
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateSetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
return null; return null;
} }
} }

@ -17,11 +17,19 @@ namespace Connected
public NumericConverter() public NumericConverter()
{ {
SetFunc = OnSet;
GetFunc = OnGet;
} }
private T OnGet(double value) protected override double ConvertValue(T? value)
{
return OnSet(value);
}
protected override T? ConvertValueBack(double value)
{
return OnGet(value);
}
private T OnGet(double value)
{ {
try try
{ {
@ -33,42 +41,42 @@ namespace Connected
return (T)(object)value.ToString(Culture); return (T)(object)value.ToString(Culture);
// sbyte // sbyte
else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) else if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?))
return (T)(object)Convert.ToSByte(value); return (T)(object)System.Convert.ToSByte(value);
// byte // byte
else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) else if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?))
return (T)(object)Convert.ToByte(value); return (T)(object)System.Convert.ToByte(value);
// short // short
else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) else if (typeof(T) == typeof(short) || typeof(T) == typeof(short?))
return (T)(object)Convert.ToInt16(value); return (T)(object)System.Convert.ToInt16(value);
// ushort // ushort
else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) else if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?))
return (T)(object)Convert.ToUInt16(value); return (T)(object)System.Convert.ToUInt16(value);
// int // int
else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) else if (typeof(T) == typeof(int) || typeof(T) == typeof(int?))
return (T)(object)Convert.ToInt32(value); return (T)(object)System.Convert.ToInt32(value);
// uint // uint
else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) else if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?))
return (T)(object)Convert.ToUInt32(value); return (T)(object)System.Convert.ToUInt32(value);
// long // long
else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) else if (typeof(T) == typeof(long) || typeof(T) == typeof(long?))
return (T)(object)Convert.ToInt64(value); return (T)(object)System.Convert.ToInt64(value);
// ulong // ulong
else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) else if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?))
return (T)(object)Convert.ToUInt64(value); return (T)(object)System.Convert.ToUInt64(value);
// float // float
else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) else if (typeof(T) == typeof(float) || typeof(T) == typeof(float?))
return (T)(object)Convert.ToSingle(value); return (T)(object)System.Convert.ToSingle(value);
// decimal // decimal
else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) else if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?))
return (T)(object)Convert.ToDecimal(value); return (T)(object)System.Convert.ToDecimal(value);
else else
{ {
UpdateGetError($"Conversion to type {typeof(T)} not implemented"); TriggerError($"Conversion to type {typeof(T)} not implemented");
} }
} }
catch (Exception e) catch (Exception e)
{ {
UpdateGetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
return default(T); return default(T);
} }
return default(T); return default(T);
@ -90,63 +98,63 @@ namespace Connected
return double.Parse((string)(object)arg, NumberStyles.Any, Culture); return double.Parse((string)(object)arg, NumberStyles.Any, Culture);
// sbyte // sbyte
if (typeof(T) == typeof(sbyte)) if (typeof(T) == typeof(sbyte))
return Convert.ToDouble((sbyte)(object)arg); return System.Convert.ToDouble((sbyte)(object)arg);
if (typeof(T) == typeof(sbyte?)) if (typeof(T) == typeof(sbyte?))
return Convert.ToDouble(((sbyte?)(object)arg).Value); return System.Convert.ToDouble(((sbyte?)(object)arg).Value);
// byte // byte
if (typeof(T) == typeof(byte)) if (typeof(T) == typeof(byte))
return Convert.ToDouble((byte)(object)arg); return System.Convert.ToDouble((byte)(object)arg);
if (typeof(T) == typeof(byte?)) if (typeof(T) == typeof(byte?))
return Convert.ToDouble(((byte?)(object)arg).Value); return System.Convert.ToDouble(((byte?)(object)arg).Value);
// short // short
if (typeof(T) == typeof(short)) if (typeof(T) == typeof(short))
return Convert.ToDouble((short)(object)arg); return System.Convert.ToDouble((short)(object)arg);
if (typeof(T) == typeof(short?)) if (typeof(T) == typeof(short?))
return Convert.ToDouble(((short?)(object)arg).Value); return System.Convert.ToDouble(((short?)(object)arg).Value);
// ushort // ushort
if (typeof(T) == typeof(ushort)) if (typeof(T) == typeof(ushort))
return Convert.ToDouble((ushort)(object)arg); return System.Convert.ToDouble((ushort)(object)arg);
if (typeof(T) == typeof(ushort?)) if (typeof(T) == typeof(ushort?))
return Convert.ToDouble(((ushort?)(object)arg).Value); return System.Convert.ToDouble(((ushort?)(object)arg).Value);
// int // int
else if (typeof(T) == typeof(int)) else if (typeof(T) == typeof(int))
return Convert.ToDouble((int)(object)arg); return System.Convert.ToDouble((int)(object)arg);
else if (typeof(T) == typeof(int?)) else if (typeof(T) == typeof(int?))
return Convert.ToDouble(((int?)(object)arg).Value); return System.Convert.ToDouble(((int?)(object)arg).Value);
// uint // uint
else if (typeof(T) == typeof(uint)) else if (typeof(T) == typeof(uint))
return Convert.ToDouble((uint)(object)arg); return System.Convert.ToDouble((uint)(object)arg);
else if (typeof(T) == typeof(uint?)) else if (typeof(T) == typeof(uint?))
return Convert.ToDouble(((uint?)(object)arg).Value); return System.Convert.ToDouble(((uint?)(object)arg).Value);
// long // long
else if (typeof(T) == typeof(long)) else if (typeof(T) == typeof(long))
return Convert.ToDouble((long)(object)arg); return System.Convert.ToDouble((long)(object)arg);
else if (typeof(T) == typeof(long?)) else if (typeof(T) == typeof(long?))
return Convert.ToDouble(((long?)(object)arg).Value); return System.Convert.ToDouble(((long?)(object)arg).Value);
// ulong // ulong
else if (typeof(T) == typeof(ulong)) else if (typeof(T) == typeof(ulong))
return Convert.ToDouble((ulong)(object)arg); return System.Convert.ToDouble((ulong)(object)arg);
else if (typeof(T) == typeof(ulong?)) else if (typeof(T) == typeof(ulong?))
return Convert.ToDouble(((ulong?)(object)arg).Value); return System.Convert.ToDouble(((ulong?)(object)arg).Value);
// float // float
else if (typeof(T) == typeof(float)) else if (typeof(T) == typeof(float))
return Convert.ToDouble((float)(object)arg); return System.Convert.ToDouble((float)(object)arg);
else if (typeof(T) == typeof(float?)) else if (typeof(T) == typeof(float?))
return Convert.ToDouble(((float?)(object)arg).Value); return System.Convert.ToDouble(((float?)(object)arg).Value);
// decimal // decimal
else if (typeof(T) == typeof(decimal)) else if (typeof(T) == typeof(decimal))
return Convert.ToDouble((decimal)(object)arg); return System.Convert.ToDouble((decimal)(object)arg);
else if (typeof(T) == typeof(decimal?)) else if (typeof(T) == typeof(decimal?))
return Convert.ToDouble(((decimal?)(object)arg).Value); return System.Convert.ToDouble(((decimal?)(object)arg).Value);
else else
{ {
UpdateSetError("Unable to convert to double from type " + typeof(T).Name); TriggerError("Unable to convert to double from type " + typeof(T).Name);
return double.NaN; return double.NaN;
} }
} }
catch (FormatException e) catch (FormatException e)
{ {
UpdateSetError("Conversion error: " + e.Message); TriggerError("Conversion error: " + e.Message);
return double.NaN; return double.NaN;
} }
} }

@ -1,61 +1,69 @@
namespace Connected using Connected.Components;
namespace Connected;
public class RangeConverter<T> : ToStringConverter<Range<T>>
{ {
public class RangeConverter<T> : Converter<Components.Range<T>> readonly DefaultConverter<T> _converter;
{
readonly DefaultConverter<T> _converter; public RangeConverter()
{
_converter = new DefaultConverter<T>();
}
public RangeConverter() protected override string? ConvertValue(Range<T>? value)
{ {
_converter = new DefaultConverter<T>(); return OnSet(value);
}
SetFunc = OnSet; protected override Range<T>? ConvertValueBack(string? value)
GetFunc = OnGet; {
} return OnGet(value);
}
private Components.Range<T> OnGet(string value) private Range<T> OnGet(string value)
{ {
if (!Split(value, out var valueStart, out var valueEnd)) if (!Split(value, out var valueStart, out var valueEnd))
return null; return null;
return new Components.Range<T>(_converter.Get(valueStart), _converter.Get(valueEnd)); return new Range<T>(_converter.ConvertBack(valueStart), _converter.ConvertBack(valueEnd));
} }
private string OnSet(Components.Range<T> arg) private string OnSet(Range<T> arg)
{ {
if (arg == null) if (arg == null)
return string.Empty; return string.Empty;
return Join(_converter.Set(arg.Start), _converter.Set(arg.End)); return Join(_converter.Convert(arg.Start), _converter.Convert(arg.End));
} }
public static string Join(string valueStart, string valueEnd) public static string Join(string valueStart, string valueEnd)
{ {
if (string.IsNullOrEmpty(valueStart) && string.IsNullOrEmpty(valueEnd)) if (string.IsNullOrEmpty(valueStart) && string.IsNullOrEmpty(valueEnd))
return string.Empty; return string.Empty;
return $"[{valueStart};{valueEnd}]"; return $"[{valueStart};{valueEnd}]";
} }
public static bool Split(string value, out string valueStart, out string valueEnd) public static bool Split(string value, out string valueStart, out string valueEnd)
{ {
valueStart = valueEnd = string.Empty; valueStart = valueEnd = string.Empty;
if (string.IsNullOrEmpty(value) || value[0] != '[' || value[^1] != ']') if (string.IsNullOrEmpty(value) || value[0] != '[' || value[^1] != ']')
{ {
return false; return false;
} }
var idx = value.IndexOf(';'); var idx = value.IndexOf(';');
if (idx < 1) if (idx < 1)
{ {
return false; return false;
} }
valueStart = value[1..idx]; valueStart = value[1..idx];
valueEnd = value[(idx + 1)..^1]; valueEnd = value[(idx + 1)..^1];
return true; return true;
} }
}
} }

Loading…
Cancel
Save